抽象工厂模式也是一种创建型的设计模式,其是在工厂模式的基础上实现更高程度的内聚。我们知道在工厂模式中,一种产品类就需要新建个对应的工厂类生成产品的实例,这会有什么问题呢?
虽然工厂模式解决了简单工厂模式不好扩展的问题,实现了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原则有没有很好的遵守,而且通过更加地抽象化,也增加了代码的理解难度。
没有万能的设计模式,只有合适的,有的时候也不必过于拘泥于规则,实际编码中,尽量遵守,寻找到合适的模式,让代码实现高内聚、低耦合、可扩展。
参考:
标签:func,优缺点,模式,工厂,golang,实例,产品,设计模式,type From: https://www.cnblogs.com/davis12/p/17446368.html