设计模式之抽象工厂模式

           继续沿着前一篇文章的思路,我们在工厂方法模式中提到:为了增加新产品同时避免对整个系统产生影响,我们提出了将工厂类抽象化的方法。那么,现在让我们来思考

这样一个问题,如果我们继续将产品抽象会怎么样呢?这就是我们今天要学习的抽象工厂模式。

          抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式包括四种角色,抽象工厂角色、具体工厂角色、抽象产品角色、具体产品角色。

          抽象工厂角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。

          具体工厂角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。

          抽象产品角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。

          具体产品角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。

          为了方便我们理解抽象工厂模式,我们引入一个产品族的概念。  所谓产品族,是指位于不同产品等级结构中,功能相关联的产品组成的家族。一般是位于不同的等级结构中的相同位置上。显然,每一个产品族中含有产品的数目,与产品等级结构的数目是相等的,形成一个二维的坐标系,水平坐标是产品等级结构,纵坐标是产品族。叫做相图。当有多个不同的等级结构的产品时,如果使用工厂方法模式就势必要使用多个独立的工厂等级结构来对付这些产品的等级结构。如果这些产品等级结构是平行的,会导致多个平行的工厂等级结构。抽象工厂模式使用同一个 工厂等级结构负责这些不同产品等级结构产品对象的创建。抽象工厂模式使用同一个 工厂等级结构负责这些不同产品等级结构产品对象的创建。

通过引进抽象工厂模式,可以处理具有相同(或者相似)等级结构的多个产品族中的产品对象的创建问题。由于每个具体工厂角色都需要负责两个不同等级结构的产品对象的创建,因此每个工厂角色都需要提供两个工厂方法,分别用于创建两个等级结构的产品。既然每个具体工厂角色都需要实现这两个工厂方法,所以具有一般性,不妨抽象出来,移动到抽象工厂角色中加以声明。(到这一刻为止,这个模式我自己都云里雾里的)
 下面我们通过具体的代码来学习使用这个模式:
 首先是抽象工厂角色
/// <summary>
    /// 这是一个抽象工厂,生产抽象产品A、抽象产品B
    /// </summary>
    abstract class AbstractFactory
    {
        //生产产品A的抽象方法
        abstract public AbstractProductA CreatProductA();
        //生产产品B的抽象方法
        abstract public AbstractProductB CreatProductB();
    }
       具体工厂角色
/// <summary>
    /// 产品生产者
    /// </summary>
    class ProductCreator1:AbstractFactory
    {
        public override AbstractProductA CreatProductA()
        {
            return new ProductA1();
        }

        public override AbstractProductB CreatProductB()
        {
            return new ProductB1();
        }
    }

 /// <summary>
    /// 产品生产者
    /// </summary>
    class ProductCreator2:AbstractFactory
    {
        public override AbstractProductA CreatProductA()
        {
            return new ProductA2();
        }

        public override AbstractProductB CreatProductB()
        {
            return new ProductB2();
        }
    }
            抽象产品角色
/// <summary>
    /// 抽象的产品A,包含一个抽象的方法
    /// </summary>
    abstract class AbstractProductA
    {
        abstract public void AboutProduct();

    }
/// <summary>
    /// 抽象的产品B,包含一个抽象的方法
    /// </summary>
    abstract class AbstractProductB
    {
        abstract public void AboutProduct();
    }
 具体产品角色
class ProductA1:AbstractProductA
    {

        public override void AboutProduct()
        {
            Console.WriteLine("这是产品A1");
        }
    }

/// <summary>
    /// 产品A2
    /// </summary>
    class ProductA2:AbstractProductA
    {

        public override void AboutProduct()
        {
            Console.WriteLine("这是产品A2");
        }
    }

/// <summary>
    /// 产品B1
    /// </summary>
    class ProductB1:AbstractProductB
    {
        public override void AboutProduct()
        {
            Console.WriteLine("这是产品B1");
        }
    }

class ProductB2:AbstractProductB
    {
        /// <summary>
        /// 产品B2
        /// </summary>
        public override void AboutProduct()
        {
            Console.WriteLine("这是产品B2");
        }
    }
          对于这一模式,目前公认的一些观点是:当出现下列情况时,建议使用抽象工厂模式
 1.系统不依赖于产品类实例如何被创建,组合和表达的细节。
 2.系统的产品有多于一个的产品族,而系统只消费其中某一族的产品(抽象工厂模式的原始用意Unix&Windows)
 3.同属于同一个产品族是在一起使用的。这一约束必须在系统的设计中体现出来。
 4.系统提供一个产品类的库,所有产品以同样的接口出现,从而使客户端不依赖于实现。
 总之,设计模式属于内功,需要很深的积累才能够理解,在一切处于未知的时候,姑且称之为不可说吧!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云来雁去

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值