前置文章: 设计模式的原则
其他设计模式:用心理解设计模式专栏
设计模式相关代码已统一放至 我的 Github
一、定义
创建型模式之一。
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
(为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类)
二、结构解析
抽象工厂模式的一般结构有四种角色:抽象工厂、具体工厂、抽象产品、具体产品。
它的角色组成和 工厂方法模式 的角色组成是一致的。并且,它也为创建产品对象提供了一个接口(抽象工厂)。
不同的是,工厂方法模式中,提供了一个用于创建对象的方法(一个工厂与一个产品相对应);而抽象工厂模式的抽象工厂类中,提供了一组用于创建对象的方法(一个工厂与一个产品等级相对应,其中每个方法分别负责创建不同族属的产品对象),派生出的不同具体工厂类来代表不同产品等级。
使用时,不需要指定具体产品类来new,而是,先选择一个具体工厂(确定产品等级),再选择一个工厂中的用于创建产品对象的方法(确定产品族属)。(这样就能决定出将要创建 哪级哪族 的具体产品)
因为里式替换原则,这里也不需要用具体产品类来接收产生的产品对象,用抽象产品类接收即可。
三、评价
抽象工厂模式针对性地解决了具有 两重不同修饰 / (等级+族属式) / 二维表格式 特征的产品对象的创建问题。
等级对应具体工厂类,族属对应抽象产品类。(等级和族属在一定情况下可交换维度进行实现。
如:
具有两重不同修饰,毛长度 和 不同动物
具有两重不同修饰,男女 和 公斤级
四、实现
namespace AbstractFactory
{
#region 抽象层
//抽象产品类
public abstract class AbstractProduct { }
//抽象产品 X族
public abstract class AbstractProductX : AbstractProduct { }
//抽象产品 Y族
public abstract class AbstractProductY : AbstractProduct { }
//抽象工厂:定义两个接口,生产X族产品,也生产Y族产品。
public abstract class AbstractCreator
{
public abstract AbstractProductX CreateProductX();
public abstract AbstractProductY CreateProductY();
}
#endregion
#region 具体层
//具体工厂, 生产A级X族,A级Y族产品
public class CretorA : AbstractCreator
{
public override AbstractProductX CreateProductX() { return new ProductAX(); }
public override AbstractProductY CreateProductY() { return new ProductAY(); }
}
//具体工厂, 生产B级X族,B级Y族产品
public class CretorB : AbstractCreator
{
public override AbstractProductX CreateProductX() { return new ProductBX(); }
public override AbstractProductY CreateProductY() { return new ProductBY(); }
}
//具体产品,A级X族
public class ProductAX : AbstractProductX { }
//具体产品,A级Y族
public class ProductAY : AbstractProductY { }
//具体产品,B级X族
public class ProductBX : AbstractProductX { }
//具体产品,B级Y族
public class ProductBY : AbstractProductY { }
#endregion
public class Client
{
//客户类 只依赖抽象工厂和抽象产品类, 不依赖实际工厂和产品类
//
public void Main()
{
//建造不同等级的工厂
AbstractCreator cretorA = new CretorA();
AbstractCreator cretorB = new CretorB();
//在工厂类中创建抽象产品的具体子类的实例。
//通过A级工厂生产X族产品
AbstractProduct productAX = cretorA.CreateProductX();
//通过A级工厂生产Y族产品
AbstractProduct productAY = cretorA.CreateProductY();
//通过B级工厂生产X族产品
AbstractProduct productBX = cretorB.CreateProductX();
//通过B级工厂生产Y族产品
AbstractProduct productBY = cretorB.CreateProductY();
}
}
}
五、新增产品等级和族属
继续参照此图, 因为 等级对应具体工厂类,族属对应抽象产品类。
1.等级新增时,要新增一个具体工厂类(C级...),另外要新增一批同等级的具体产品类,覆盖每个族属(上图一横行)。
2.族属新增时,要新增一个抽象产品类(Z族...),另外要新增一批同族属的具体产品类,覆盖每个等级(上图一竖行)。
特别的: 新增族属时,要修改抽象工厂类,以新增一个创建新族属产品的抽象方法(抽象工厂承担着定义“创建产品的接口方法”的职责),此时,所有的具体工厂类也要随之修改(实现该抽象方法)。
可见,等级新增易,族属新增难(违背开闭原则)
六、扩展维度的设想
如何从 两重不同修饰 / (等级+族属式) / 二维表格式 扩展为 三重不同修饰 / ?+ (等级+族属式) / 三维表格式 ?
甚至更多维。
如: 在此基础上增加毛的颜色。
TODO