抽象工厂模式与工厂模式类似,被认为是工厂方法模式的另一层抽象.抽象工厂模式围绕创建其他工厂的超级工厂工作.
1.角色:
1.1抽象产品:
构成产品系列的一组不同但相关的产品的声明接口.
1.2具体产品:
实现抽象产品接口的类,主要用于定义产品对象,由相应的具体工厂创建.
1.3抽象工厂:
创建抽象产品对象的操作接口.
1.4具体工厂:
实现抽象工厂接口的类.用于创建产品对象.每个具体工厂都会生产相应的具体产品.
1.5客户端:
通过抽象接口调用抽象工厂对象和抽象产品对象,客户端能与所有具体工厂或具体产品交互.
2.抽象工厂使用场景:
2.1出于对代码未来扩展性考虑.不希望代码基于具体产品进行构建,可以使用抽象工厂模式.
2.2某个类具有一组抽象方法,并且这个类功能不够明确,可以考虑抽象工厂模式.
2.3如果一个类需要与多种类型的产品交互,可以考虑将工厂方法抽取到具备完整功能的抽象工厂接口中.
3.实现方式:
3.1抽象产品接口:
package itboStudy
import "fmt"
// 抽象产品接口
type AbstractProduct interface {
GetName()
}
// 具体产品类
type Computer struct {
}
//具体产品类中的方法
func (c *Computer) GetName() {
fmt.Println("具体产品Computer")
}
3.2抽象工厂接口:
//抽象工厂接口
type AbstractFactory interface {
CreateProduct() AbstractProduct
}
3.3具体工厂类及方法:
// 具体工厂类
type ComputerProductFactory struct{}
// 初始化具体工厂对象.
func NewComputerProductFactory() ComputerProductFactory {
return ComputerProductFactory{}
}
// 使用具体工厂对象创建具体产品
func (com *ComputerProductFactory) CreateProduct() Computer {
return Computer{}
}
3.4客户端:
func main() {
factory := itboStudy.NewComputerProductFactory()
product := factory.CreateProduct()
product.GetName()
}
4.实战:
4.1抽象接口:
// 电子产品工厂
type InterfaceElectronicFactory interface {
MakeComputer() InterfaceComputer
}
// 获取电子产品工厂对象
func GetElectronicFactory(brand string) (*LenovoFactory, error) {
if brand == "电脑" {
return &LenovoFactory{}, nil
}
return nil, fmt.Errorf("%s", "error brand type")
}
4.2具体工厂类:
// 定义具体工厂类
type LenovoFactory struct{}
// 生成联想电脑
func (com *LenovoFactory) MakeComputer() *LenovoComputer {
return &LenovoComputer{
Computer: Computer{
color: "black",
size: 14,
},
}
}
4.3抽象产品接口:
type InterfaceComputer interface {
SetColor(color string)
SetSize(size int)
Getcolor() string
Getsize() int
}
type Computer struct {
color string
size int
}
func (com *Computer) SetColor(color string) {
com.color = color
}
func (com *Computer) SetSize(size int) {
com.size = size
}
func (com *Computer) GetSize() int {
return com.size
}
func (com *Computer) GetColor() string {
return com.color
}
4.4具体产品类:
// 定义具体产品
type LenovoComputer struct {
Computer
}
4.5客户端:
func main() {
factory, _ := itboStudy.GetElectronicFactory("电脑")
computer := factory.MakeComputer()
fmt.Printf("computer:%#v\n", computer.GetColor())
}
5优点:
客户端不知道创建什么类型对象时.
抽象工厂实现了具体的隔离.
抽象工厂可以轻松改变产品系列.
保证产品一致性.
6.缺点:
抽象工厂难以扩展新型产品.如果要支持新型产品需要扩展工厂接口.
可以迟到,但是不会缺席.