抽象工厂模式概念
抽象工厂模式是一种设计模式,它允许创建一系列相关的对象,而无需指定具体的类。具体来说,抽象工厂定义了用于创建不同产品的接口,但实际的创建工作则由具体的工厂类完成。每个具体工厂负责创建一组相关的产品,这些产品在一起使用时是兼容的。
抽象工厂模式的精髓在于它提供了一种 将对象的创建与使用解耦 的方法,使得客户端代码可以在不依赖具体类的情况下创建和使用一系列相关的对象。以下是抽象工厂模式的核心精髓和优点:
1. 产品族的创建
抽象工厂模式允许创建一系列相关或相互依赖的对象,而不仅仅是一个对象。通过抽象工厂,客户端可以一次性获取到一组互相兼容的产品。例如,使用不同的工厂,可以轻松切换不同风格的家具(现代或古典),而无需更改客户端代码。
2. 解耦
客户端代码与具体的产品类解耦。客户端通过抽象工厂接口与具体工厂进行交互,而不需要知道具体的产品类或如何创建这些产品。这样,产品的具体实现细节与客户端代码隔离开来,客户端只依赖于抽象工厂和产品接口。
3. 一致性保证
通过确保产品的一致性来维护产品的兼容性。例如,抽象工厂模式可以保证创建的桌子和椅子是同一风格的,并且它们能够很好地配合在一起使用。这对于需要保证一组相关产品的兼容性是很重要的。
4. 易于扩展
当需要引入新的产品变体(如新风格的家具)时,只需创建新的具体工厂类来实现新的产品组。客户端代码无需修改,只需要使用新的工厂即可。这使得系统具有很好的扩展性和灵活性。
5. 集中管理
将对象的创建集中在工厂中,可以更容易地管理和维护这些对象的创建逻辑。例如,可以在工厂中实现对象的缓存、初始化或其他复杂的创建逻辑,而客户端代码只关注对象的使用,而不关心其创建过程。
例子:家具工厂
在这个例子中,我们有一个家具工厂的系统。每个工厂生产不同风格的家具,像是现代风格和古典风格。
概念映射
- 抽象工厂接口(
FurnitureFactory
):定义了创建各种家具的方法,比如创建桌子和椅子。 - 具体工厂类(
ModernFurnitureFactory
和ClassicFurnitureFactory
):实现了抽象工厂接口,负责创建具体风格的家具。 - 产品接口(
Table
和Chair
):定义了家具的公共行为。 - 具体产品类(
ModernTable
、ModernChair
、ClassicTable
和ClassicChair
):实现了具体的家具样式。
实现
1. 抽象工厂接口
// FurnitureFactory 定义了创建各种家具的方法
type FurnitureFactory interface {
CreateTable() Table
CreateChair() Chair
}
2. 具体工厂类
// ModernFurnitureFactory 现代家具工厂
type ModernFurnitureFactory struct{}
func (f *ModernFurnitureFactory) CreateTable() Table {
return &ModernTable{}
}
func (f *ModernFurnitureFactory) CreateChair() Chair {
return &ModernChair{}
}
// ClassicFurnitureFactory 古典家具工厂
type ClassicFurnitureFactory struct{}
func (f *ClassicFurnitureFactory) CreateTable() Table {
return &ClassicTable{}
}
func (f *ClassicFurnitureFactory) CreateChair() Chair {
return &ClassicChair{}
}
3. 产品接口
// Table 家具接口:桌子
type Table interface {
Style() string
}
// Chair 家具接口:椅子
type Chair interface {
Style() string
}
4. 具体产品类
// ModernTable 现代桌子
type ModernTable struct{}
func (t *ModernTable) Style() string {
return "现代桌子"
}
// ModernChair 现代椅子
type ModernChair struct{}
func (c *ModernChair) Style() string {
return "现代椅子"
}
// ClassicTable 古典桌子
type ClassicTable struct{}
func (t *ClassicTable) Style() string {
return "古典桌子"
}
// ClassicChair 古典椅子
type ClassicChair struct{}
func (c *ClassicChair) Style() string {
return "古典椅子"
}
5. 客户端代码
func main() {
var factory FurnitureFactory
// 选择现代家具工厂
factory = &ModernFurnitureFactory{}
fmt.Println(factory.CreateTable().Style()) // 输出: 现代桌子
fmt.Println(factory.CreateChair().Style()) // 输出: 现代椅子
// 选择古典家具工厂
factory = &ClassicFurnitureFactory{}
fmt.Println(factory.CreateTable().Style()) // 输出: 古典桌子
fmt.Println(factory.CreateChair().Style()) // 输出: 古典椅子
}
总结
在这个例子中:
- 抽象工厂接口
FurnitureFactory
定义了创建家具的方法。 - 具体工厂
ModernFurnitureFactory
和ClassicFurnitureFactory
实现了这个接口,负责创建具体风格的家具。 - 产品接口
Table
和Chair
定义了家具的通用行为。 - 具体产品
ModernTable
、ModernChair
、ClassicTable
和ClassicChair
实现了具体风格的家具。
通过这种方式,客户端代码只与抽象工厂接口和产品接口交互,不需要关心具体的产品实现细节。只要替换工厂类,就可以很方便地切换不同风格的家具,而不需要修改客户端代码。