通俗易懂设计模式解析——抽象工厂模式

前言

  前面介绍了单例模式及工厂模式相关知识及示例,今天主要介绍的是抽象工厂模式,上一篇我们讲了工厂模式。将创建对象的任务委托给子类,延迟创建。解决工厂中责任的划分。实现具体工厂与产品之间的一一对应。解决的是”单个对象”的问题。

  华为工厂除了生产华为手机之外。肯定也会有原件配套的充电线和耳机。这时工厂对应的是一套产品该如何解决了呢?显然不再适合使用工厂模式了。今天将的抽象工厂模式将会比较好的解决此问题。抽象工厂模式解决的是”一系列对象”的问题、解决多套变化的问题。

抽象工厂模式介绍

一、来由

  在我们编程的过程中难免会出现”一系列相互依赖对象”的创建问题,往往会有由于需要的改变增加或减少对象的创建。为了面对解决这种”一系列的相互依赖的对象”的创建工作的紧密耦合性,出现了其解决方案——抽象工厂模式。

二、意图

  提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

三、案例图

 

 

四、与工厂模式区别

工厂模式:

1、解决单个对象的问题

2、工厂类与产品类一一对应关系

抽象工厂模式:

1、解决一系列对象的问题

2、工厂类与产品类是一对多的关系(一对应一系列想依赖的产品)

工厂模式讲的是一个华为手机工厂生产一个华为手机,要生产其他的产品需另加工厂。抽象工厂模式讲的是一个华为手机工厂可以生产一系列的华为手机产品(手机、耳机、充电器)。

五、抽象工厂模式代码示例

  根据上一篇文章的事例我们进行扩展,进一步讲述抽象工厂模式的使用。抽象工厂模式我们工厂类对应的多个产品的生产。华为手机工厂生产华为手机、华为耳机、华为充电器等。下面我们看看抽象工厂模式的具体实现:

 

namespace Abstract_Factory
{ 
    #region 抽象产品类  ===============
    /// <summary>
    /// 手机抽象类
    /// </summary>
    public abstract class Phone
    {
        public abstract  string CreatePhone();
    }
    /// <summary>
    /// 耳机抽象类
    /// </summary>
    public abstract class Headset
    {
        public abstract string CreateHeadset();
    }
    /// <summary>
    /// 充电器抽象类
    /// </summary>
    public abstract class Charger
    {
        public abstract string CreateCharger();
    }
    #endregion

    #region 华为具体产品类  ===========
    public class HuaweiPhone : Phone
    {
        public override string CreatePhone()
        {
            return "华为手机一号现世";
        }
    }
    public class HuaweiHeadset : Headset
    {
        public override string CreateHeadset()
        {
            return "华为手机一号原配耳机";
        }
    }
    public class HuaweiCharger : Charger
    {
        public override string CreateCharger()
        {
            return "华为手机一号原配充电器";
        }
    }
    #endregion

    #region 小米具体产品类  =========== 
    public class XiaomiPhone : Phone
    {
        public override string CreatePhone()
        {
            return "小米手机一号现世";
        }
    }
    public class XiaomiHeadset : Headset
    {
        public override string CreateHeadset()
        {
            return "小米手机一号原配耳机";
        }
    }
    public class XiaomiCharger : Charger
    {
        public override string CreateCharger()
        {
            return "小米手机一号原配充电器";
        }
    }
    #endregion

    #region 抽象工厂类  ===============
    /// <summary>
    /// 抽象工厂类
    /// </summary>
    public abstract class AbstractFactory
    {
        public abstract Phone GetPhone();
        public abstract Headset GetHeadset();
        public abstract Charger GetCharger();
    }
    #endregion

    #region 华为具体工厂===============
    public class HuaweiFactory : AbstractFactory
    {

        public override Phone GetPhone()
        {
            return new HuaweiPhone();
        }

        public override Headset GetHeadset()
        {
            return new HuaweiHeadset();
        }
         
        public override Charger GetCharger()
        {
            return new HuaweiCharger();
        }
    }
    #endregion

    #region 小米具体工厂===============
    public class XiaomiFactory : AbstractFactory
    {

        public override Phone GetPhone()
        {
            return new XiaomiPhone();
        }

        public override Headset GetHeadset()
        {
            return new XiaomiHeadset();
        }

        public override Charger GetCharger()
        {
            return new XiaomiCharger();
        }
    }
    #endregion 
}

 

    class Program
    {
        static void Main(string[] args)
        {
            ///华为工厂生产华为产品
            HuaweiFactory huaweiFactory = new HuaweiFactory();
            var phone = huaweiFactory.GetPhone().CreatePhone();
            var headset = huaweiFactory.GetHeadset().CreateHeadset();
            var charger = huaweiFactory.GetCharger().CreateCharger();
            Console.WriteLine("华为产品生产:" + phone + "——" + headset + "——" + charger);


            ///小米工厂生产小米产品
            XiaomiFactory xiaomiFactory = new XiaomiFactory();
            phone = xiaomiFactory.GetPhone().CreatePhone();
            headset = xiaomiFactory.GetHeadset().CreateHeadset();
            charger = xiaomiFactory.GetCharger().CreateCharger();
            Console.WriteLine("小米产品生产:" + phone + "——" + headset + "——" + charger);
             

            Console.ReadLine();
        }
    }

 

这是系列产品新增了一个魅族手机,我们看看如何修改增加魅族手机的生产:

    #region 新增魅族手机需求===========
    public class MeizuPhone : Phone
    {
        public override string CreatePhone()
        {
            return "魅族手机一号现世";
        }
    }
    public class MeizuHeadset : Headset
    {
        public override string CreateHeadset()
        {
            return "魅族手机一号原配耳机";
        }
    }
    public class MeizuCharger : Charger
    {
        public override string CreateCharger()
        {
            return "魅族手机一号原配充电器";
        }
    }
    public class MeizuFactory : AbstractFactory
    { 
        public override Phone GetPhone()
        {
            return new MeizuPhone();
        }
        public override Headset GetHeadset()
        {
            return new MeizuHeadset();
        }
        public override Charger GetCharger()
        {
            return new MeizuCharger();
        }

    }
    #endregion

 

            ///魅族工厂生产小米产品
            MeizuFactory meizuFactory = new MeizuFactory();
            phone = meizuFactory.GetPhone().CreatePhone();
            headset = meizuFactory.GetHeadset().CreateHeadset();
            charger = meizuFactory.GetCharger().CreateCharger();
            Console.WriteLine("魅族产品生产:" + phone + "——" + headset + "——" + charger);

这里我们可以发现新增系列产品(魅族系列)比较方便,而且吻合”开放扩展——封闭修改”的原则。扩展起来还是比较方便的,但是也是存在着一定的问题的。当我们新增新的产品的时候,这个时候就需要去系列产品生产抽象工厂去增加产品的生产方法。同时也需要在各个子类中增加其方法。这也就违背了开闭原则。这也就是抽象方法的一个缺点所在。

使用场景及优缺点

一、使用场景

1、在系统中如果存在一系列相互依赖的产品。这系列变化比较多。且存在着多套系列的产品的时候。我们就可以考虑使用抽象工厂模式了。

2、强调一系列相关的产品对象设计的时候。

3、一个系统由多个相互依赖项进行配置且需要多个系统时。

二、优点

1、当一个产品系列,对个对象使用时,保证使用的是同系列中的对象

2、降低了具体产品和具体类及客户端之间的耦合性。通过使用抽象类相关联而不是具体类。

3、对系列产品的修改增加极其方便

三、缺点

1、在系列产品中新增产品困难并且违反了开闭原则

总结

  到这里抽象工厂模式我们就暂时的介绍完了。今天呢又介绍了创建型中的一种设计模式,设计模式的学习之路还很漫长。一切都才刚刚开始。学习更重要的是灵活运用,举一反三。选择适当的场景去使用适当的模式。多思考其优点缺点和使用场景。抽象工厂在针对于系列产品的修改增加时符合开闭原则。但是在系列产品中的产品修改增加的时候又违反了开闭原则。我们在使用每一种设计模式时都得慎重选择。

   只要认为是对的就去做,坚持去做,不要在乎别人的看法,哪怕是错,至少你有去做过证明曾经你努力过。

 

 

  C#设计模式系列目录

 

欢迎大家扫描下方二维码,和我一起踏上设计模式的闯关之路吧!

 

  

 

posted @ 2019-08-26 16:50 小世界的野孩子 阅读(...) 评论(...) 编辑 收藏
回到顶部