设计模式 2
- 创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
- 结构型模式(7):适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式
- 行为型模式(11):责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式
抽象工厂模式(Abstract Factory Pattern)
1 定义
抽象工厂模式提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。它适用于需要创建多个产品族的情况。
2 结构
抽象工厂模式包含以下角色:
- 抽象工厂(AbstractFactory): 声明创建一系列相关对象的接口。
- 具体工厂(ConcreteFactory): 实现抽象工厂中的创建方法,生成具体产品。
- 抽象产品(AbstractProduct): 为每种产品声明接口。
- 具体产品(ConcreteProduct): 定义由具体工厂创建的产品对象,必须实现抽象产品接口。
UML 类图
+-------------------------+
| AbstractFactory |
+-------------------------+
| + CreateProductA() |
| + CreateProductB() |
+-------------------------+
/|\
|
+-------------------------+
| ConcreteFactory1 |
+-------------------------+
| + CreateProductA() |
| + CreateProductB() |
+-------------------------+
|
+-------------------------+
| ConcreteFactory2 |
+-------------------------+
| + CreateProductA() |
| + CreateProductB() |
+-------------------------+
/|\
|
+----------------------------+ +----------------------------+
| AbstractProductA | | AbstractProductB |
+----------------------------+ +----------------------------+
| + OperationA() | | + OperationB() |
+----------------------------+ +----------------------------+
/|\ /|\
| |
+----------------------------+ +----------------------------+
| ProductA1 | | ProductB1 |
+----------------------------+ +----------------------------+
| + OperationA() | | + OperationB() |
+----------------------------+ +----------------------------+
|
+----------------------------+
| ProductA2 |
+----------------------------+
| + OperationA() |
+----------------------------+
3 示例代码
假设我们要创建两种风格的家具:现代风格和维多利亚风格,每种风格包括椅子和沙发。我们可以使用抽象工厂模式来实现。
// 抽象产品A:椅子
public interface IChair
{
void SitOn();
}
// 抽象产品B:沙发
public interface ISofa
{
void LieOn();
}
// 具体产品A1:现代椅子
public class ModernChair : IChair
{
public void SitOn()
{
Console.WriteLine("Sitting on a modern chair.");
}
}
// 具体产品B1:现代沙发
public class ModernSofa : ISofa
{
public void LieOn()
{
Console.WriteLine("Lying on a modern sofa.");
}
}
// 具体产品A2:维多利亚椅子
public class VictorianChair : IChair
{
public void SitOn()
{
Console.WriteLine("Sitting on a Victorian chair.");
}
}
// 具体产品B2:维多利亚沙发
public class VictorianSofa : ISofa
{
public void LieOn()
{
Console.WriteLine("Lying on a Victorian sofa.");
}
}
// 抽象工厂
public interface IFurnitureFactory
{
IChair CreateChair();
ISofa CreateSofa();
}
// 具体工厂1:现代家具工厂
public class ModernFurnitureFactory : IFurnitureFactory
{
public IChair CreateChair()
{
return new ModernChair();
}
public ISofa CreateSofa()
{
return new ModernSofa();
}
}
// 具体工厂2:维多利亚家具工厂
public class VictorianFurnitureFactory : IFurnitureFactory
{
public IChair CreateChair()
{
return new VictorianChair();
}
public ISofa CreateSofa()
{
return new VictorianSofa();
}
}
// 客户端代码
class Program
{
static void Main(string[] args)
{
IFurnitureFactory modernFactory = new ModernFurnitureFactory();
IChair modernChair = modernFactory.CreateChair();
ISofa modernSofa = modernFactory.CreateSofa();
modernChair.SitOn();
modernSofa.LieOn();
IFurnitureFactory victorianFactory = new VictorianFurnitureFactory();
IChair victorianChair = victorianFactory.CreateChair();
ISofa victorianSofa = victorianFactory.CreateSofa();
victorianChair.SitOn();
victorianSofa.LieOn();
}
}
4 特点
- 优点:
- 遵循开放-关闭原则:可以通过添加新的具体工厂来扩展产品家族,而不修改现有代码。
- 保证产品族的一致性:所有由同一具体工厂创建的产品都是相互兼容的。
- 缺点:
- 复杂度较高:随着产品族和具体产品的增加,类的数量会显著增加。
- 扩展困难:增加新的产品族时,必须修改抽象工厂及其子类,这违反了开放-关闭原则。
5 适用场景
- 当系统要创建多个产品族的对象时。
- 当你需要确保一个产品族中的所有对象是兼容的时。
- 当产品族的创建逻辑较为复杂,需要封装起来时。
6 比较总结
- 工厂方法模式:
- 适用于创建单一产品的场景。
- 通过子类化具体创建者来扩展产品类型。
- 工厂方法模式更关注的是"如何创建"一个对象。
- 抽象工厂模式:
- 适用于创建多个相关产品的场景。
- 通过增加新的具体工厂来扩展产品族。
- 抽象工厂模式更关注的是"创建什么"(一系列相关的对象)。
在实际应用中,工厂方法模式较适合较简单的对象创建场景,而抽象工厂模式则适合更复杂的、多产品族的对象创建需求。