• 设计模式 2/23 工厂模式(二)


    先要给各位同学灌输一个思想,世间本无设计模式,用的人多了,自然就有了

    没有太明显的优劣之分,只道是谁更适合

    如果没法理解<<工厂>>,建议阅读上一篇 设计模式 2/23 工厂模式(一) ,毕竟是一个渐进明细的过程,急不来的

    这一篇分享 工厂模式

    回想一下简单工厂,我们把具体类的实例化工作放在一个工厂方法里面来执行.

    同时故意在上一篇提到了开放-封闭原则.

    仔细想象看看上一篇的代码,到底有没有遵守这个原则,或者说这个原则有没有被严格意义的遵守,或者说遵守的程度是多少。

    如果我们要新增一种Email的处理,我们需要修改的是工厂,在工厂里面加case ,break,这个事实业务扩展了,但是代码修改了,如果使用工厂方法,我们可以避免这种修改工厂的情况

    保持一个对扩展开发,对修改关闭的原则

    工厂模式 定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

    敲黑板的时候又来了

    定义一个接口,让子类决定实例化哪一个工厂,创建过程延迟到子类进行。怎么理解,怎么破,怎么办!

    想象这样一个场景,我们知道世界制造业霸主,富士康集团,几乎覆盖了所有电子产品的制造,如 手机,鼎盛时期,苹果,摩托,诺基亚,等等,都是由其制造。

    而这些制造又是由富士康旗下的子公司进行制造,比如现在叫富智康的公司,当时就是生产诺基亚,而现在的郑州富士康,专注苹果的生产

    这个时候,我们理解富士康就是一个接口,他高傲的告诉全世界,我可以生产手机,我的子公司,只要实现我,就会制造手机。我们是弱关系,我们是聚合,我的子公司必须实现制造手机同时也可以制造电脑!!!

    于是乎,各个子公司就是富士康的子类,对每个子公司来讲,只有在子公司内部,才会去具体生产对应的手机

    当你想生产苹果手机的时候,你来到富士康的大门,问,苹果生产厂怎么走,然后就得到指引,一路闻着味寻去

    重点,你,你想生产苹果手机,不是富士康想生产苹果手机,决定权,选择权是在你,客户端,而不是工厂

    仔细琢磨,其中的微妙,以前是你告诉富士康你要生产苹果手机,然后富士康去决定让谁生产,现在是你决定让富士康的某个厂为你生产苹果手机,

    你-富士康-厂

    你-富士康的厂

    细微的差别,带来的是无穷的烦恼

    讲完怎么理解,我们看看代码怎么实现。依然用我们上一篇对应的例子,

    处理不同类型的文件,有音频的,视频的,图片的,文本的

    采用工厂模式,先定义一个接口,

        /// <summary>
        /// 处理工厂接口
        /// </summary>
        public interface IHandleFactory
        {
            /// <summary>
            /// 创建具体的工厂
            /// </summary>
            /// <returns></returns>
            Handle CreateHandle();
        }
    View Code

    然后,让其子类自己决定实例化哪一个工厂类

    音频处理工厂

        /// <summary>
        /// 音频处理工厂
        /// </summary>
        public class AudioHandleFactory : IHandleFactory
        {
            /// <summary>
            /// 我实例化 音频处理
            /// </summary>
            /// <returns></returns>
            public Handle CreateHandle()
            {
                return new AudioHandle();
            }
        }
    View Code

    图片处理工厂

        /// <summary>
        /// 图片处理工厂
        /// </summary>
        public class ImageHandleFactory : IHandleFactory
        {
            /// <summary>
            /// 我实例化 图片处理
            /// </summary>
            /// <returns></returns>
            public Handle CreateHandle()
            {
                return new ImageHandle();
            }
        }
    View Code

    文本处理工厂

        /// <summary>
        /// 文本处理工厂
        /// </summary>
        public class TextHandleFactory : IHandleFactory
        {
            /// <summary>
            /// 我实例化 文本处理
            /// </summary>
            /// <returns></returns>
            public Handle CreateHandle()
            {
                return new TextHandle();
            }
        }
    View Code

    然后具体的处理方法类和以前一样

        /// <summary>
        /// 抽象类 处理
        /// </summary>
        public abstract class Handle
        {
            /// <summary>
            /// 处理文件
            /// </summary>
            public abstract void HandleFile();
        }
    
    
       /// <summary>
        /// 图片处理类
       /// </summary>
        public class ImageHandle : Handle
        {
            public override void HandleFile()
            {
                Console.WriteLine("我开始处理图片文件了");
            }
        }
    
    
        /// <summary>
        /// 文本处理类
        /// </summary>
        public class TextHandle : Handle
        {
            public override void HandleFile()
            {
                Console.WriteLine("我开始处理文本文件了");
            }
        }
    
    
        /// <summary>
        /// 音频处理工厂
        /// </summary>
        public class AudioHandleFactory : IHandleFactory
        {
            /// <summary>
            /// 我实例化 音频处理
            /// </summary>
            /// <returns></returns>
            public Handle CreateHandle()
            {
                return new AudioHandle();
            }
        }
    View Code

    我们看客户端怎么调用

      static void Main()
            {
                var handleFactory=new AudioHandleFactory();
                var handle = handleFactory.CreateHandle();
                handle.HandleFile();
            }
    View Code

    OK,以上就是工厂模式

    不要指指点点,不要指指点点

    我知道,昨天的那种情况应该按照如下写

     static void Main()
            {
                IHandleFactory handleFactory = null;
                var fileType = "Image";
                switch (fileType)
                {
                    case "Audio":
                        handleFactory = new AudioHandleFactory();
                        break;
                    case "Image":
                        handleFactory = new ImageHandleFactory();
                        break;
                    case "Text":
                        handleFactory = new TextHandleFactory();
                        break;
                }
                if (handleFactory != null)
                {
                    var handle = handleFactory.CreateHandle();
                    handle.HandleFile();
                }
                Console.ReadLine();
            }
    View Code

    这样才符合题意

    我知道,还是有case,break, 但是我们已经把判断提到了客户端,仔细琢磨下,和最初的写方法,判断,再到后续的简单工厂模式,但现在的工厂模式,一不一不的进化,细微的差别,程序的可扩展性,仔细回味

    仍然不要急,我们最终是会使用反射利器,干掉switch的

    总结下

    优点

    1、一个调用者想创建一个对象,只要知道其名称就可以了。

    2、高扩展性,如果想增加一个产品,只要扩展一个工厂类和一个产品类就可以。

    3、屏蔽产品的具体实现,调用者只关心产品的接口。

    缺点

    每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

    系统越做越复杂,到底是一开始的写方法调用直接调用方便,还是现在工厂模式方便,其实是根据现实业务进行选择的

    以上就是关于工厂模式的分享

    一路前行,风雨无阻,不定时更新,原计划是明天晚上更新,但明天会不家,所以提前更新 

  • 相关阅读:
    【转】Python爬虫(5)_性能相关
    【转】Python爬虫(4)_selenium模块
    【转】Python爬虫(3)_Beautifulsoup模块
    【转】Python爬虫_示例2
    【转】Python爬虫_示例
    linux开机自启动tomcat
    Linux下Tomcat启动,停止命令
    Linux下tomcat启动Neither the JAVA_HOME nor the JRE_HOME environment variable is defined At least one of
    centos7开启关闭80端口
    centos安装JDK
  • 原文地址:https://www.cnblogs.com/LionelMessi/p/7461210.html
Copyright © 2020-2023  润新知