抽象工厂模式的优缺点:
优点:
-
拥有工厂方法模式的优点
-
当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
-
增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点:
- 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。
适用场景:
-
系统中有多于一个的产品族。而每次只使用其中某一产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。
-
产品等级结构稳定。设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。
代码样例:
package main
import "fmt"
// ======= 抽象层 =========
type AbstractApple interface {
ShowApple()
}
type AbstractBanana interface {
ShowBanana()
}
type AbstractPear interface {
ShowPear()
}
//抽象工厂
type AbstractFactory interface {
CreateApple() AbstractApple
CreateBanana() AbstractBanana
CreatePear() AbstractPear
}
// ======== 实现层 =========
/* 中国产品族 */
type ChinaApple struct {}
func (ca *ChinaApple) ShowApple() {
fmt.Println("中国苹果")
}
type ChinaBanana struct {}
func (cb *ChinaBanana) ShowBanana() {
fmt.Println("中国香蕉")
}
type ChinaPear struct {}
func (cp *ChinaPear) ShowPear() {
fmt.Println("中国梨")
}
type ChinaFactory struct {}
func (cf *ChinaFactory) CreateApple() AbstractApple {
var apple AbstractApple
apple = new(ChinaApple)
return apple
}
func (cf *ChinaFactory) CreateBanana() AbstractBanana {
var banana AbstractBanana
banana = new(ChinaBanana)
return banana
}
func (cf *ChinaFactory) CreatePear() AbstractPear {
var pear AbstractPear
pear = new(ChinaPear)
return pear
}
/* 日本产品族 */
type JapanApple struct {}
func (ja *JapanApple) ShowApple() {
fmt.Println("日本苹果")
}
type JapanBanana struct {}
func (jb *JapanBanana) ShowBanana() {
fmt.Println("日本香蕉")
}
type JapanPear struct {}
func (cp *JapanPear) ShowPear() {
fmt.Println("日本梨")
}
type JapanFactory struct {}
func (jf *JapanFactory) CreateApple() AbstractApple {
var apple AbstractApple
apple = new(JapanApple)
return apple
}
func (jf *JapanFactory) CreateBanana() AbstractBanana {
var banana AbstractBanana
banana = new(JapanBanana)
return banana
}
func (cf *JapanFactory) CreatePear() AbstractPear {
var pear AbstractPear
pear = new(JapanPear)
return pear
}
/* 美国产品族 */
type AmericanApple struct {}
func (aa *AmericanApple) ShowApple() {
fmt.Println("美国苹果")
}
type AmericanBanana struct {}
func (ab *AmericanBanana) ShowBanana() {
fmt.Println("美国香蕉")
}
type AmericanPear struct {}
func (ap *AmericanPear) ShowPear() {
fmt.Println("美国梨")
}
type AmericanFactory struct {}
func (af *AmericanFactory) CreateApple() AbstractApple {
var apple AbstractApple
apple = new(AmericanApple)
return apple
}
func (af *AmericanFactory) CreateBanana() AbstractBanana {
var banana AbstractBanana
banana = new(AmericanBanana)
return banana
}
func (af *AmericanFactory) CreatePear() AbstractPear {
var pear AbstractPear
pear = new(AmericanPear)
return pear
}
// ======== 业务逻辑层 =======
func main() {
//需求1: 需要美国的苹果、香蕉、梨 等对象
//1-创建一个美国工厂
var aFac AbstractFactory
aFac = new(AmericanFactory)
//2-生产美国苹果
var aApple AbstractApple
aApple = aFac.CreateApple()
aApple.ShowApple()
//3-生产美国香蕉
var aBanana AbstractBanana
aBanana = aFac.CreateBanana()
aBanana.ShowBanana()
//4-生产美国梨
var aPear AbstractPear
aPear = aFac.CreatePear()
aPear.ShowPear()
//需求2: 需要中国的苹果、香蕉
//1-创建一个中国工厂
cFac := new(ChinaFactory)
//2-生产中国苹果
cApple := cFac.CreateApple()
cApple.ShowApple()
//3-生产中国香蕉
cBanana := cFac.CreateBanana()
cBanana.ShowBanana()
}
- 简单工厂模式:一个工厂负责创建所有产品
-
- 违反“开闭原则”,添加新产品需要修改工厂逻辑,工厂越来越复杂
- 工厂方法模式:一个工厂创建一个产品
-
- 系统的可扩展性也就变得非常好,无需修改接口和原类
- 增加系统中类的个数,复杂度和理解度增加(一个具体产品就需要对应一个具体工厂)
- 抽象方法模式:一个工厂创建一系列(一个产品族)的产品
-
- 增加新的产品族很方便,无须修改已有系统,符合“开闭原则”
- 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,违背了“开闭原则”
- 相当于在工厂方法模式的基础下进行了折中
-
-
- 对于产品族来说遵循了开闭原则
- 对于产品等级结构来说没有遵循开闭原则
- 如果产品结构等级稳定,那么就相当于完全遵循开闭原则
-