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

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

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

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

这一篇分享 工厂模式spa

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

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

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

若是咱们要新增一种Email的处理,咱们须要修改的是工厂,在工厂里面加case ,break,这个事实业务扩展了,可是代码修改了,若是使用工厂方法,咱们能够避免这种修改工厂的状况htm

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

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

敲黑板的时候又来了

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

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

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

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

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

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

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

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

你-富士康-厂

你-富士康的厂

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

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

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

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

    /// <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的

总结下

优势

一、一个调用者想建立一个对象,只要知道其名称就能够了。

二、高扩展性,若是想增长一个产品,只要扩展一个工厂类和一个产品类就能够。

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

缺点

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

 

系统越作越复杂,究竟是一开始的写方法调用直接调用方便,仍是如今工厂模式方便,实际上是根据现实业务进行选择的

 

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

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

相关文章
相关标签/搜索