2.15 Go之工厂模式自动注册
什么是自动注册
示例调用:
import "database/sql"
import _ "github.com/go-sql-driver/mysql"
解析:
明明没有使用github.com/go-sql-driver/mysql包却还是需要导入的原因:
这个包是mysql的驱动包,database/sql定义了一些规范,不同实现者可以根据这个规范实现自己的驱动,然后通过 import _ github.com/go-sql-driver/mysql" 将驱动注册到database/sql中。使用者只需要根据database/sql来操作数据库,而不用去关心驱动具体是怎么做的。
原因:
具体在上面的Go包初始化过程当中有讲解到
Goland的自动注册
golang的包如果包含有init函数,那么会在import的时候执行这个函数(在执行main之前执行的init)
我们可以利用这个特性,实现自动注册
代码结构:
clsfactory
├── main.go
└── base
└── factory.go
└── cls1
└── reg.go
└── cls2
└── reg.go
factory.go:
package base
/* 创建一个接口 */
type Class interface {
Do()
}
/* 定义一个变量,保存接口注册好的信息 */
var (
// 保存注册好的工厂信息
/*
map的key是字符串,func() Class是一个返回值为Class接口对象的函数作为map的value
提供给工厂方注册使用,所谓的“工厂”,就是一个定义为func() Class的普通函数,调用此函数,创建一个类实例,实现的工厂内部结构体会实现Class接口
*/
factoryByName = make(map[string]func() Class)
)
/* 注册器,类生成工厂 */
func Register(name string, factory func() Class) error {
if "" != name {
// 设置工厂名称
factoryByName[name] = factory
}
return nil
}
/* 根据名称创建对应的类接口对象 */
func Create(name string) Class {
if "" != name {
/*
在已经注册的信息中查找名字对应的工厂函数,找到后,在下一行调用并返回接口
*/
if f, ok := factoryByName[name]; ok {
return f()
}else {
panic("未找到该名称!")
}
}
return nil
}
cls1.go:
package cls1
import (
"GoPracticeClsFactory/base"
"fmt"
)
/*
定义一个结构体
实现base包下的class接口
定义初始化的init()函数
*/
/* 定义一个结构体1 */
type Class1 struct {
}
/* 实现factory下的class接口 */
func (c *Class1) Do() {
fmt.Println("HelloWorld!")
}
/* 定义init()初始化函数 */
func init() {
base.Register("Class1", func() base.Class{
// 闭包写法,具体函数内容在使用时自行定义
return new(Class1)
})
}
cls2.go:
package cls2
import (
"GoPracticeClsFactory/base"
"fmt"
)
/*
定义结构体
实现factory文件下的接口
定义init()方法
*/
/* 定义结构体 */
type Class2 struct {
}
func (c *Class2) Do() {
fmt.Println("Class2")
}
func init() {
// 启动注册器自动注册class2工厂--->调用base包下定义的函数
base.Register("Class2", func() base.Class {
return new(Class2)
})
}
在main.go文件中进行调用:
package main
/*
调用前面的三个目录下定义文件下的函数
*/
import (
"GoPracticeClsFactory/base"
)
func main() {
// 创建c1实例
c1:= base.Create("Class1")
// 调用接口下的函数
c1.Do()
// 创建c2实例
c2 := base.Create("Class2")
c2.Do()
}
It's a lonely road!!!

浙公网安备 33010602011771号