工厂模式是创建型设计模式中使用比较多的一种模式,它最基本的思想就是将类的最终用户与类的实现抽象分离出去,比如用户想获取类的某个属性的值,只需要提供接口给他就可以了,用户无需关系是从数据库读取的还是通过restapi去获取的。使用工厂模式的指导思想有三点
1. 将对象的创建与结构体定义分离出去,放在别的模块
2. 面向接口而不是具体的实现
3. 将对象分组便于实现创建的代码逻辑
下面以一个实际应用中的例子介绍工厂模式。
在一个实际项目中需要用到三种的容器runtime,包括docker,containerd,cri-o.由于每种runtime处理容器(创建容器,获得容器状态等)的方式是不一样的,因此每种容器需要单独定义自己的结构体和函数有自己的NewContainerHandler函数。
套用工厂模式我们可以把每个runtime的创建放在工厂里面做。工厂函数可以返回接口而不是结构体。因为接口允许您在不公开内部实现的情况下定义行为。这意味着我们可以将结构设为私有,而仅仅在包外部公开接口。
首先我们定义工厂类,基于go语言面向接口编程的思想来定义工厂接口。根据指导思想对象创建与结构提分离出去,我们定义一个接口用于对象创建主要为NewContainerHandler他用来创建一个runtime实例,返回的对象是实现了ContainerHandler接口的实例。我们的这三种runtime就是要去实现ContainerHandler的实例。具体的代码如下(比实际项目中的代码略有缩减):
工厂接口:ContainerHandlerFactory接口中后面的方法起到一些辅助的功能,比如返回这个factory的名字,这个factory是否能够处理指定的container,以及Debug信息等
type ContainerHandlerFactory interface {
// Create a new ContainerHandler using this factory. CanHandleAndAccept() must have returned true.
NewContainerHandler(name string, inHostNamespace bool) (c ContainerHandler, err error)
// Returns whether this factory can handle and accept the specified container.
Ca