用心理解设计模式——抽象工厂模式 (Abstract Factory Pattern)

前置文章: 用心理解设计模式——设计模式的原则 

设计模式相关代码已统一放至 我的 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

猜你喜欢

转载自blog.csdn.net/NRatel/article/details/84255567