《C#设计模式》 工厂三兄弟之 【简单工厂模式】,【工厂方法模式】,【抽象工厂模式】

《C#设计模式》 三种工厂设计模式

  1. 【简单工厂模式】

  2. 【工厂方法模式】

  3. 【抽象工厂模式】

第一种:简单工厂模式

一:【简单工厂模式】

简单工厂模式概念(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。

二: 案例分析

使用简单工厂模式设计一个可以创建不同几何形状(如圆形、方形和三角形等)的绘图工具,每个几何图形都具有绘制draw()和擦除erase()两个方法;

 首先定义一个接口类;包含两个方法;绘制;擦除;


    public interface Draws
    {
        //绘制图形
        void draw();
        //擦除图形
        void erase();
    }

再在某个具体产品类继承这个Draws接口;以下为三种图形实现方式;

  //==============================================================
    //  作者:zhoupei
    //  时间:2019/2/18 14:12:11
    //  文件名:Circular
    //  版本:V1.0.1  
    //  说明:圆形具体产品类     
    //==============================================================
    class Circular : Draws
    {
        public void draw()
        {
            Console.WriteLine("绘制圆形图形");
        }
        public void erase()
        {
            Console.WriteLine("擦除圆形图形");
        }

    }


 class Rectangle : Draws
    {
        //绘制矩形
        public void draw()
        {
            Console.WriteLine("绘制矩形图形");
        }
        //擦除矩形
        public void erase()
        {
            Console.WriteLine("擦除矩形图形");
        }
    }

  class Triangle: Draws
    {
        public void draw()
        {
            Console.WriteLine("绘制三角形图形");
        }

        public void erase()
        {
            Console.WriteLine("擦除三角形图形");
        }
    }

再写个图形处理工厂类,静态工厂方法;

 class FigureFactory
    {
        //静态工厂方法
        public static Draws Getfigure(string figtype)
        {
            Draws dws = null;
            switch (figtype.ToLower())
            {
                case "rectangle":
                    dws = new Rectangle();
                    break;
                case "triangle":
                    dws = new Rectangle();
                    break;
                case "circular":
                    dws = new Rectangle();
                    break;
                default:
                    dws = null;
                    break;
            }
            return dws;
        }
    }

客户端调用方法,这里根据读取全局配置文件的方式来获取路径;

添加app.config文件;配置路径;

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="figureType" value="Circular"/>  //传入圆形
  </appSettings>
</configuration>

Main函数调用方法;

 static void Main(string[] args)
        {
            Draws dw;
            string figurestr = ConfigurationSettings.AppSettings["figureType"];
            dw = FigureFactory.Getfigure(figurestr);
            dw.draw();//绘制 - 圆形
            dw.erase();//擦除 - 圆形
            Console.ReadLine();
        }

优缺点总结:

 1. 主要优点

       简单工厂模式的主要优点如下:

       (1) 工厂类包含必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的职责,而仅仅“消费”产品,简单工厂模式实现了对象创建和使用的分离。

       (2) 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以在一定程度减少使用者的记忆量。

       (3) 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

         2. 主要缺点

       简单工厂模式的主要缺点如下:

       (1) 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。

       (2) 使用简单工厂模式势必会增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度。

       (3) 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。

       (4) 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
 

第二种:工厂方法模式

工厂方法模式概念:工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern)。工厂方法模式是一种类创建型模式。

案例分析:使用工厂方法模式设计一个程序来读取各种不同类型的图片格式,针对每一种图片格式都设计一个图片读取器,如GIF图片读取器用于读取GIF格式的图片、JPG图片读取器用于读取JPG格式的图片。需充分考虑系统的灵活性和可扩展性。

首先定义图片接口  即抽象产品类;代码如下!

 /// <summary>
    /// 图片处理接口 
    /// 抽象产品:它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类。
    /// </summary>
    interface Imager
    {
        void GetImages();
    }

然后定义抽象工工厂类; 代码如下!

 interface ImagerFactory
    {
        Imager GetImagelist(); //抽象产品工厂类
    }

现在客户需求里要分别读取处理JPG格式的图片跟GIF格式的图片;

具体产品类

    //==============================================================
    //  作者:zhoupei
    //  时间:2019/2/18 11:45:23
    //  文件名:GifImg
    //  版本:V1.0.1  
    //  说明:Gif图片 - 具体产品类    
    //==============================================================
    class GifImg : Imager
    {
        public void GetImages()
        {
            Console.WriteLine("读取GIF图片。");
        }
    }

    class JpgImg : Imager
    {
        public void GetImages()
        {
            Console.WriteLine("读取Jpg图片。");
        }
    }

 

具体产品工厂

 //==============================================================
    //  作者:zhoupei
    //  时间:2019/2/18 11:46:05
    //  文件名:GifImgFactory
    //  版本:V1.0.1  
    //  说明:产品具体工厂 
    //==============================================================
    class GifImgFactory : ImagerFactory  //继承自抽象产品类
    {
        public Imager GetImagelist()
        {
            Imager im = new GifImg();
            return im;
        }
    } 
    


    class JpgImgFactory : ImagerFactory
    {
        public Imager GetImagelist()
        {
            Imager im = new JpgImg();
            return im;
        }
    }

客户端Main()调用: 方式跟以上一样

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="imageFactory"  value="FactoryMethod.JpgImgFactory"/>
  </appSettings>
</configuration>
  static void Main(string[] args)
        {
            ImagerFactory ifc;
            Imager img;
            string factStr = ConfigurationManager.AppSettings["imageFactory"];
            ifc = (JpgImgFactory)Assembly.Load("FactoryMethod").CreateInstance(factStr);
            img = ifc.GetImagelist();
            img.GetImages();

            Console.ReadLine();
        }

工厂方法模式总结:

 1. 主要优点

       工厂方法模式的主要优点如下:

       (1) 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。

       (2) 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够让工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,就正是因为所有的具体工厂类都具有同一抽象父类。

       (3) 使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了,这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。

      2. 主要缺点

     工厂方法模式的主要缺点如下:

      (1) 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。

      (2) 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。

第三中:抽象工厂模式

抽象工厂模式概述:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。

案例分析:某个软件公司欲推出一款新的手机游戏软件,该软件能够支持Symbian、Android和Windows Mobile等多个智能手机操作系统平台,针对不同的手机操作系统,该游戏软件提供了不同的游戏操作控制(OperationController)类和游戏界面控制(InterfaceController)类,并提供相应的工厂类来封装这些类的初始化过程。软件要求具有较好的扩展性以支持新的操作系统平台,为了满足上述需求,试采用抽象工厂模式对其进行设计。

具体实现:

//抽象产品类
  interface Android
    {
        void Description();
    }

  interface Apple
    {
        void Description();
    } 

  interface ASymbian
    {
        void Description();
    }

抽象工厂类:

/// <summary>
    /// 游戏支持系统抽象工厂
    /// </summary>
    interface GameFactory
    {
        ASymbian CanRunonSymbian();
        Android CanRunonAndroid();
        Apple CanRunonApple();
    }

具体产品类

    //==============================================================
    //  作者:zhoupei
    //  时间:2019/2/18 16:08:35
    //  文件名:InterfaceControllerOnAndroid
    //  版本:V1.0.1  
    //  说明:安卓系统支持InterfaceControllerOnAndroid
    //==============================================================
    class InterfaceControllerOnAndroid : Android
    {
        public void Description()
        {
            Console.WriteLine("安卓系统支持InterfaceControllerOnAndroid游戏操作控制");
        }
    }

    class InterfaceControllerOnApple : Apple
    {
        public void Description()
        {
            Console.WriteLine("苹果支持 InterfaceController游戏操作控制");
        }
    }

    class InterfaceControllerOnSymbian :ASymbian
    {
        public void Description()
        {
            Console.WriteLine("塞班系统支持InterfaceController游戏操作控制");
        }
    }





    //==============================================================
    //  作者:zhoupei
    //  时间:2019/2/18 16:07:45
    //  文件名:OperationControllerOnAndroid
    //  版本:V1.0.1  
    //  说明:支持OperationController 
    //==============================================================
    class OperationControllerOnAndroid :Android
    {
        public void Description()
        {
            Console.WriteLine("安卓系统支持OperationControllerOnAndroid游戏操作控制");
        }
    }

    class OperationControllerOnApple : Apple
    {
        public void Description()
        {
            Console.WriteLine("苹果系统支持OperationController游戏操作控制");
        }
    } 

    class OperationControllerOnSymbian : ASymbian
    {
        public void Description()
        {
            Console.WriteLine("塞班系统支持OperationController游戏操作控制");
        }
    }

具体工厂类:

    //==============================================================
    //  作者:zhoupei
    //  时间:2019/2/18 16:10:59
    //  文件名:B_InterfaceController
    //  版本:V1.0.1  
    //  说明:
    //==============================================================
    class B_InterfaceController : GameFactory
    {
        public Android CanRunonAndroid()
        {
            return new InterfaceControllerOnAndroid();
        }

        public Apple CanRunonApple()
        {
            return new InterfaceControllerOnApple();
        }

        public ASymbian CanRunonSymbian()
        {
            return new InterfaceControllerOnSymbian();
        }

    }


    class B_OperationController : GameFactory
    {
        public Android CanRunonAndroid()
        {
            return new OperationControllerOnAndroid();
        }

        public Apple CanRunonApple()
        {
            return new OperationControllerOnApple();
        }

        public ASymbian CanRunonSymbian()
        {
            return new OperationControllerOnSymbian();
        }
    }

抽象工厂模式总结

    1. 主要优点

       抽象工厂模式的主要优点如下:

       (1) 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。

       (2) 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。

       (3) 增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。

       2. 主要缺点

       抽象工厂模式的主要缺点如下:

       增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。

三种工厂方式学习总结完毕,欢迎指正,讨论指教;

学习来自我的大学老师《C#设计模式》,感谢恩师;

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值