golang实现设计模式之抽象工厂模式总结-代码、优缺点、适用场景
抽象工厂模式也是一种创建型的设计模式,其是在工厂模式的基础上实现更高程度的内聚。我们知道在工厂模式中,一种产品类就需要新建个对应的工厂类生成产品的实例,这会有什么问题呢?
虽然工厂模式解决了简单工厂模式不好扩展的问题,实现了OCP,但一种产品就需要新建一个工厂类,比如有10000种产品,是不是也是新建10000个工厂类呢?看到没,这就是问题所在,即使利于扩展,无奈代码臃肿,而且有些产品可以提出共性,尽量复用就成为了改进的目标。
抽象工厂模式就是实现了比较好的内聚,将原来工厂模式下的一种产品类等级,优化为多个有一定关联的产品类聚合在一起。
下面老规矩,看看抽象模式的优缺点、适用场景、代码实现。
优缺点
- 优点
1.具备工厂方法的优点。
2.同时由于可以聚合多个产品族的共性,不用创建新类来管理。
- 缺点
1.产品族的扩展将是一件十分费力的事情。新增产品时,所有工厂类需要联动修改,所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。
适用场景
- 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
代码实现
package main import "fmt" func main() { var f factory f = new(concreteFactoryA) p := f.createPhoneFactory() p.use() w := f.createSmartWatchFactory() w.healthWatcher() } // 1.cellphone interface type iCellphone interface { use() } // 1.smart watch interface type iSmartWatch interface { healthWatcher() } // 2.concrete cellphone product type iphoneProduct struct { } func (r *iphoneProduct) use() { fmt.Println("Iphone can be dialing.") } type miPhoneProduct struct { } func (r *miPhoneProduct) use() { fmt.Println("miPhone can be dialing.") } type iWatchProduct struct { } func (r *iWatchProduct) healthWatcher() { fmt.Println("iWatch can monitor your health.") } type oppoWatchProduct struct { } func (r *oppoWatchProduct) healthWatcher() { fmt.Println("oppoWatch can monitor your health.") } type phoneTyp int type watchType int const ( iphoneType = 0 + iota miPhoneTyp ) const ( iWatchType = 10000 + iota oppoWatchTyp ) // 3.factory interface type factory interface { createPhoneFactory() iCellphone createSmartWatchFactory() iSmartWatch } // 4.concrete product factory // apple product type concreteFactoryA struct { } func (r *concreteFactoryA) createPhoneFactory() iCellphone { return &iphoneProduct{} } func (r *concreteFactoryA) createSmartWatchFactory() iSmartWatch { return &iWatchProduct{} } // other brands product type concreteFactoryB struct { } func (r *concreteFactoryB) createPhoneFactory() iCellphone { return &miPhoneProduct{} } func (r *concreteFactoryB) createSmartWatchFactory() iSmartWatch { return &oppoWatchProduct{} }
工厂模式系列目前就结束了,这里做个简单总结:
-
1.简单工厂模式,客户端只要请求工厂类,传入不同的参数,进而获取到对应的产品实例,客户端不用关心其实现细节,只管获取实例使用即可,实现了创建实例与使用实例的隔离。这种设计模式适合于创建产品种类比较少的情景,如果产品种类很多,可想而知,我们都通过一个工厂类的生成方法来获取,必然涉及到修改新建实例代码,不就违背了 OCP 原则吗。所以对于新建和删除工厂方法中的相关涉及的产品,这也是问题。而且就这一个工厂方法来生成所有的产品的实例,产品多了,代码就臃肿了,使得该方法职责过重。
-
2.工厂模式,为了解决工厂方法只有一个,职责过重,工厂模式中通过一种产品对应一个具体的工厂类去实现实例的生成,一定程度上解耦了功能,另外如果新增产品,我们只需要多写个产品类和对象的工厂类及方法,这也很好的实现了 OCP原则,对扩展开放,对修改关闭。当然这也有问题,就是产品多了,每个产品都需要新建个对应的工厂类,况且有些产品也并不是完全不相关,内聚性就变差了。工厂模式适用于客户端不关心实例产生细节,另外实例的实际创建会推迟到子类工厂中实现。
-
3.抽象工厂模式,既然工厂模式每个产品都需要实现对应的工厂类去生成相关实例,提取产品的共性,提高代码的内聚性,就是抽象工厂模式要干的。在抽象工厂中,依然是不同产品对应不同的工厂类,但可以尽可能将具有相同共性的产品类别合在一起,从而提高了内聚性。但同时也带来一些问题,比如修改产品类,可能涉及到对应的工厂类都需要改动,OCP原则有没有很好的遵守,而且通过更加地抽象化,也增加了代码的理解难度。
没有万能的设计模式,只有合适的,有的时候也不必过于拘泥于规则,实际编码中,尽量遵守,寻找到合适的模式,让代码实现高内聚、低耦合、可扩展。
参考:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!