zoukankan      html  css  js  c++  java
  • C#设计模式(1)——简单工厂模式

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

    1.什么是简单工厂

    现实中的工厂负责生产产品(笔记本,鼠标,手机等等),顾名思义,编程中的简单工厂就是一个生产对象类(工厂的本质还是类Class)
    它的主要作用是创建具体的产品类实例(类似工厂创建出具体的产品)
    我们以一个生产鼠标为例来分析简单工厂的作用,鼠标有两种:戴尔鼠标和惠普鼠标,代码如下:

    //鼠标抽象类
        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("生产了一个惠普鼠标!");
            }
        }
    //定义了一个抽象类,然后用两个类,来继承母类。

    客户端代码:

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

    程序运行如下:

     我们可以看到程序运行没有问题,通过new一个DellMouse我们可以创建一个戴尔的鼠标。

    问题,如果我们不想要戴尔鼠标了,要全部生产惠普鼠标怎么办呢?
    最简单直接的方法就是把 new DellMouse全部替换成 new HpMouse。 如果我们的软件中new了100个DellMouse实例呢?
    一个一个地去替换会是一个巨大的工作量,同时通过new的方式来创建戴尔鼠标的实例,会让DellMouse类和客户端产生强耦合关系,
    这时候使用简单工厂就可以帮助我们降低耦合,减少工作量了。

    更换新的代码结构看看

        /// <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;
            }
        }

    客户端的代码就可以改成:

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

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

    配置文件:

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

    更换新的代码结构看看(使用配置文件)

         /// <summary>
        /// 鼠标工厂类
        /// </summary>
        public class MouseFactory
        {
           //从配置文件中读取品牌
            private static readonly string brand = ConfigurationManager.AppSettings["brand"];//多了这段code
            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;
            }
        }

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

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

    现在我们想把生产的鼠标都换成惠普鼠标,只需要将配置文件中的dell改成hp即可,修改配置文件后运行结果如下:

     大功告成!这时有一个问题,如果我们想生产华硕鼠标怎么办呢?

    除了添加一个继承Mouse的AsusMouse类外,
    还要在MouseFactory中添加一段case 代码。
    按照开闭原则,添加一个实现类没什么问题,开闭原则中对添加开放;
    但是修改MouseFactory工厂类就违背了对修改闭合的原则了。
    后边的工厂模式就是专门用来解决这个问题的。

    上面的主要的代码迭代就是:

    通过1:继承抽象类(或者继承接口)-----》简单工厂类-----》简单工厂类(配置文件从配置文件读取)

    简单工厂的优点:

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

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

    简单工厂的缺点:

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

    人各有命,上天注定,有人天生为王,有人落草为寇。脚下的路,如果不是你自己的选择,那么旅程的终点在哪,也没人知道。你会走到哪,会遇到谁,都不一定。
  • 相关阅读:
    codeblocks多文件联合编译
    C++顶层const和底层const的区别
    keras failed to create cublas handle:CUBLAS_STATUS_ALLOC_FAILED问题
    Notepad++强大的代码补全和代码提示功能的方法
    PEP8编码风格
    在Maven项目中使用easypoi完成Excel文件上传下载
    Restful风格,使用同一地址,访问不同的方法
    注解@NoRepositoryBean的作用
    注解@MappedSuperclass的作用
    Shiro整合Spring以及权限登陆过滤
  • 原文地址:https://www.cnblogs.com/ZkbFighting/p/14072204.html
Copyright © 2011-2022 走看看