zoukankan      html  css  js  c++  java
  • c#设计模式(4)——抽象工厂模式

    一、引言

            在上一专题中介绍了工厂方法模式,工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码),而工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性。但是在现实生活中,一个工厂只创建单个产品这样的例子很少,因为现在的工厂都多元化了,一个工厂创建一系列的产品,如果我们要设计这样的系统时,工厂方法模式显然在这里不适用,然后抽象工厂模式却可以很好地解决一系列产品创建的问题,这是本专题所要介绍的内容。

          部分内容选自https://www.cnblogs.com/zhili/p/SingletonPatterm.html,感觉写得很好,我只是自己总结成自己的东西。

    二、介绍

               一个工厂负责一些产品的创建,即产品簇。单一职责就是创建完整的产品簇,抽象工厂类抽象出实现的产品方法,具体产品工厂类当继承抽象类后,必须显式的override父类的抽象方法。即这样子理解,玩游戏时有红方和蓝方,红方会产生英雄和小兵,蓝方也会产生英雄和小兵,两者有共同之处又有不同之处,可以有红色工厂创建红方英雄和小兵,蓝方工厂产生蓝方英雄和小兵。抽象人物对象肯定是英雄和小兵了,具体实现就是红方和蓝方了。工厂抽象类就是创建英雄和小兵,继承工厂抽象类的红方工厂就是创建红方英雄和红方小兵了,蓝方工厂就是创建蓝方英雄和蓝方小兵啦。       

           1.先来指定英雄和小兵(英语含义和内容不搭,别介意,懒得改程序了)

     public interface IArmy
        {
            /// <summary>
            /// show出Army
            /// </summary>
            void ShowArmy();
        }
    
    
      public interface IRace
        {
            /// <summary>
            /// show出王者
            /// </summary>
            void ShowKing();
        }
    

      2.接下来就是红方和蓝方的小兵和英雄具体功能实现啦,红方小兵和英雄继承了基类,实现了红方英雄和小兵独特技能,同理,蓝方小兵和英雄也继承了基类,实现了独特技能。 现在想想也知道,有两方的英雄和小兵都具体实现了,接下来就有个管理工厂,来创建两方的小兵和英雄。

       

    /// <summary>
        /// 实现具体实现方法
        /// </summary>
        public class NE : IRace
        {
            public void ShowKing()
            {
                Console.WriteLine("The King of {0} is {1}", this.GetType().Name, "Moon");
            }
        }
    
        public class NEArmy : IArmy
        {
            public void ShowArmy()
            {
                Console.WriteLine("The Army of {0} is {1}", this.GetType().Name, "大G、风骑士、蝙蝠");
            }
        }
    

      

     public class Human: IRace
        {
    
            public void ShowKing()
            {
                Console.WriteLine("The King of {0} is {1}", this.GetType().Name, "Moon");
            }
        }
    
        public class HumanArmy : IArmy
        {
            public void ShowArmy()
            {
                Console.WriteLine("The Army of {0} is {1}", this.GetType().Name, "footman,火枪,骑士,狮鹫");
            }
        }
    

      3.既然两方都有共同的需求,就是创建英雄和小兵,那就抽象出两个方法,创建英雄和创建小兵,工厂抽象类就是创建英雄和小兵的抽象方法。

           

       public abstract class AbstractFactory
        {
            public abstract IRace CreateRace();
    
            public abstract IArmy CreateArmy();
        }
    

      4.继承工厂抽象类的红方工厂就是创建红方英雄和红方小兵了,蓝方工厂就是创建蓝方英雄和蓝方小兵啦。

     public class HumanFactory : AbstractFactory
        {
            public override IArmy CreateArmy()
            {
                return new HumanArmy();
            }
    
            public override IRace CreateRace()
            {
                return new Human();
            }
        }
    

      

     public class NEFactory : AbstractFactory
        {
            public override IArmy CreateArmy()
            {
                return new NEArmy();
            }
    
            public override IRace CreateRace()
            {
                return new NE();
            }
        }
    

      5.主函数调用工厂类实现

     class Program
        {
            static void Main(string[] args)
            {
                   //创建红方工厂
                AbstractFactory redFactory = new HumanFactory();
                //红方创建并实现英雄的方法
                IArmy humanArmy = redFactory.CreateArmy();
                humanArmy.ShowArmy();
                //红方创建并实现小兵方法
                IRace humanRace = redFactory.CreateRace();
                humanRace.ShowKing();
    
                //创建蓝方工厂
                AbstractFactory blueFactory = new NEFactory();
                //蓝方创建并实现英雄方法
                blueFactory.CreateArmy().ShowArmy();
                //蓝方创建并实现小兵方法
                blueFactory.CreateRace().ShowKing();
            }
        }
    

    三、总结

           抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展,这真是抽象工厂模式的优点所在,然后抽象模式同时也存在不足的地方。下面就具体看下抽象工厂的缺点(缺点其实在前面的介绍中以已经涉及了):

            抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。

  • 相关阅读:
    JS原始类型Number数字类型
    JS数据类型基础知识
    JS基础循环语句和跳转语句
    JS对象类型数组方法篇
    JS对象类型数组基础篇
    JS基础逻辑运算符
    IE6,IE7,FF等浏览器不兼容原因及解决办法(转)
    DML、DDL、DCL区别
    Asp.net(c#)GridView分页时用图片显示上一页,下一页
    P3P完成跨域COOKIE
  • 原文地址:https://www.cnblogs.com/Qxian/p/13719710.html
Copyright © 2011-2022 走看看