C#设计模式(1)——简单工厂模式

1.什么是简单工厂

  现实中的工厂负责生产产品,顾名思义,编程中的简单工厂就是一个生产对象的类,它的主要做用是建立具体的产品类实例。咱们以一个生产鼠标为例来分析简单工厂的做用,鼠标有两种:戴尔鼠标和惠普鼠标,代码以下:编程

    //鼠标抽象类
    public abstract class Mouse
    {
        public abstract void Print();
    }


    //戴尔鼠标
    public class DellMouse : Mouse
    {
        public override void Print()
        {
            Console.WriteLine("生产了一个Dell鼠标!");
        }
    }

    //惠普鼠标
    public class HpMouse : Mouse
    {
        public override void Print()
        {
            Console.WriteLine("生产了一个惠普鼠标!");
        }
    }

客户端代码:app

    class Program
    {
        static void Main(string[] args)
        {
            Mouse mouse1 = new DellMouse();
            Mouse mouse2 = new DellMouse();
            Mouse mouse3 = new DellMouse();
            Mouse mouse4 = new DellMouse();
            Mouse mouse5 = new DellMouse();
            mouse1.Print();
        }
    }

程序运行以下:ide

  咱们能够看到程序运行没有问题,经过new一个DellMouse咱们能够建立一个戴尔的鼠标,这时有一个问题,若是咱们不想要戴尔鼠标了,要所有生产惠普鼠标怎么办呢?最简单直接的方法就是把 new DellMouse所有替换成 new HpMouse 。若是咱们的软件中new了100个DellMouse实例呢?一个一个地去替换会是一个巨大的工做量,同时经过new的方式来建立戴尔鼠标的实例,会让DellMouse类和客户端产生强耦合关系,这时候使用简单工厂就能够帮助咱们下降耦合,减小工做量了。添加一个MouseFactory简单工厂类,这个工厂类专门来建立Mouse的实例:spa

   /// <summary>
    /// 鼠标工厂类
    /// </summary>
    public class MouseFactory
    {
        private Mouse mouse = null;
        public Mouse CreateMouse(string brand)
        {
            switch (brand)
            {
                case "dell":
                    mouse = new DellMouse();
                    break;
                case "hp":
                    mouse = new HpMouse();
                    break;
                default:
                    break;
            }
            return mouse;
        }
    }

客户端的代码就能够改为:code

    class Program
    {
        static void Main(string[] args)
        {
            //实例化一个工厂类
            MouseFactory mouseFactory = new MouseFactory();
            //经过工厂类建立鼠标
            Mouse mouse1 = mouseFactory.CreateMouse("dell");
            Mouse mouse2 = mouseFactory.CreateMouse("dell");
            Mouse mouse3 = mouseFactory.CreateMouse("dell");
            Mouse mouse4 = mouseFactory.CreateMouse("dell");
            Mouse mouse5 = mouseFactory.CreateMouse("dell");
            mouse1.Print();
            Console.ReadKey();
        }
    }

  运行程序结果同样的,这样作有什么好处呢?咱们看到咱们把之前的 new DellMouse() 替换成了  mouseFactory.Create("dell") ,客户端和DellMouse的耦合变成了 客户端<-->MouseFactory<-->DellMouse形式,有效下降了客户端和DellMouse间的耦合。咱们还用一个疑问,程序改为这样的话,若是咱们想把戴尔鼠标所有换成惠普鼠标,要把工厂类的参数"dell"换成"hp",不是还要改100次?任务量没有下降呀!对于这个问题,咱们能够把品牌名brand存放在一个地方,如配置文件中,这样咱们想切换鼠标品牌时就不用修改代码,直接修改配置文件便可,以下:对象

配置文件:blog

  <appSettings>
    <add key="dbname" value="dell"/>
  </appSettings>

工厂类修改成:继承

    /// <summary>
    /// 鼠标工厂类
    /// </summary>
    public class MouseFactory
    {
       //从配置文件中读取品牌
        private static readonly string brand = ConfigurationManager.AppSettings["brand"];
        private Mouse mouse = null;
        public Mouse CreateMouse()
        {
            switch (brand)
            {
                case "dell":
                    mouse = new DellMouse();
                    break;
                case "hp":
                    mouse = new HpMouse();
                    break;
                default:
                    break;
            }
            return mouse;
        }
    }

客户端代码就不用传参数了,以下:string

    class Program
    {
        static void Main(string[] args)
        {
            //实例化一个工厂类
            MouseFactory mouseFactory = new MouseFactory();
            //经过工厂类建立鼠标
            Mouse mouse1 = mouseFactory.CreateMouse();
            Mouse mouse2 = mouseFactory.CreateMouse();
            Mouse mouse3 = mouseFactory.CreateMouse();
            Mouse mouse4 = mouseFactory.CreateMouse();
            Mouse mouse5 = mouseFactory.CreateMouse();
            mouse1.Print();
            Console.ReadKey();
        }
    }

如今咱们想把生产的鼠标都换成惠普鼠标,只须要将配置文件中的dell改为hp便可,修改配置文件后运行结果以下:产品

大功告成!这时有一个问题,若是咱们想生产华硕鼠标怎么办呢?除了添加一个继承Mouse的AsusMouse类外,还要在MouseFactory中添加一段case 代码。按照开闭原则,添加一个实现类没什么问题,开闭原则中对添加开放;可是修改MouseFactory工厂类就违背了对修改闭合的原则了。后边的工厂模式就是专门用来解决这个问题的。

2.小结

上边例子的类图:

简单工厂的优势:

  1.简单工厂能够有效地下降客户端和具体对象的耦合,将new具体对象的任务交给了一个简单工厂类

  2能够有效的进行代码复用,如客户端A和客户端B都须要一个具体对象,客户端A和客户端B能够经过同一个简单工厂来获取具体类型的实例

简单工厂的缺点:

  必定程度上违背了开闭原则,在新增产品时须要修改简单工厂类

相关文章
相关标签/搜索