zoukankan      html  css  js  c++  java
  • 设计模式学习总结工厂方法模式(Factory Method Pattern)

    问题:
    简单工厂模式比较适用于事先已经考虑到的可能出现的算法,来构造工厂类实现,如果需要添加新的类,则就需要改变工厂类了,违反开闭原则,简单的说,简单公共适应与业务变化不是很剧烈的场景下如,审批业务,设计时可以判断到的只有“部门经理审批”,“总裁审批”不会过几天又要加入“组长审批”,去修改工厂类,相对来说变化不是很剧烈的。

    在软件设计中经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口。如果我们使用简单工厂,这样会不断地修改工厂类,应对业务变化,违反开闭原则,另外因为实例化产品的判断逻辑在工厂类中,工厂类会变的越来与臃肿。

    定义:
    工厂方法模式又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂模式(Polymorphic Factory),定义一个用户创建对象的接口,让子类决定实例化哪一个类,工厂方法模式使一个类的实例化延迟到其子类。

    意图:
    定义一个用户创建对象的公共接口,此接口不负责产品的创建不关心产品实例化细节,而是将具体创建工作交给子类去做,这样做的目的是将类的实例化操作延迟到子类中完成,即由子类来决定究竟应该实例化(创建)哪一个类,使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。

    参与者:
    •抽象工厂(Creator)角色:
    是工厂方法模式的核心,声明工厂方法(FactoryMethod),返回一个产品。任何在模式中创建的对象的工厂类必须实现这个接口。
    •具体工厂(Concrete Creator)角色:
    这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,由客户调用,返回一个产品的实例 。
    •抽象产品(Product)角色:
    工厂方法模式所创建的对象产品的抽象类型。
    •具体产品(Concrete Product)角色:
    这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。

    UML图:

     


    实例说明:

    诺基亚手机工厂
    比如Nokia手机工厂,现在只生产N8,N9两款手机,如果以后生产N10手机可以不修改现有的生产逻辑可以使用工厂方法,根据不同生产工厂(N8生产车间,N9

    生产车间)创建不同的Nokia手机,而且容易加入新型号手机的生产(不修改现有系统)。uml图如下:

     
    代码:      

        /// <summary>
        
    /// 手机接口
        
    /// </summary>
        public interface INokiaPhone
        {
            string GetPhoneName();            
        }
        /// <summary>
        
    /// N8手机具体类
        
    /// </summary>
        public class N8Phone : INokiaPhone
        {
            public string GetPhoneName()
            {
                return "我是N8";
            }
        }
        /// <summary>
        
    /// N9手机具体类
        
    /// </summary>
        public class N9Phone : INokiaPhone
        {
            public string GetPhoneName()
            {
                return "我是N9";
            }
        }
        /// <summary>
        
    /// 手机抽象工厂类
        
    /// </summary>
        public interface IPhoneFactory
        {
            INokiaPhone CreateNokiaPhone();
        }
        /// <summary>
        
    /// N8手机工厂
        
    /// </summary>
        public class NokiaN8Factory : IPhoneFactory
        {
            public INokiaPhone CreateNokiaPhone()
            {
                return new N8Phone();
            }
        }
        /// <summary>
        
    /// N9手机工厂
        
    /// </summary>
        public class NokiaN9Factory : IPhoneFactory
        {
            public INokiaPhone CreateNokiaPhone()
            {
                return new N9Phone();
            }
        }
        /// <summary>
        
    /// 客户端类
        
    /// </summary>
        class Program
        {
            void CreatePhone()
            {
                IPhoneFactory factory = new NokiaN8Factory();
                INokiaPhone phone = factory.CreateNokiaPhone();
                phone.GetPhoneName();
            }
        }

    优点:

    •创建一个具体产品的细节完全封装在具体工厂内部,符合高内聚,低耦合
    •在系统中加入新产品时,无需修改抽象工厂和抽象产品提供的接口,符合开闭原则,大大提高系统扩展性

    缺点:

    •每加入一种新产品都要,创建一个产品的工厂(方法)
    •Factory模式仅仅局限于一类类(就是说Product是一类,有一个共同的基类),没办法为不同类的类提供一个对象创建的接口

    应用情景:
    •当一个类需要调用另一个类,但是并不(需要)知道具体要实例化哪一个具体的子类,希望由它的子类来指定它所创建的对象的时候。这里的意思为:假设我们在类A中要使用到类B,B是一个抽象父类,在A中并不知道具体要实例化那一个B的子类,但是在类A的子类D中是可以知道的。在A中我们没有办法直接使用类似于new ×××的语句,因为根本就不知道×××是什么。

    •简单工厂模式无法应对业务变化的时候。

  • 相关阅读:
    [翻译] GoogleMaterialDesignIcons
    [翻译] InstagramPhotoPicker
    UIButton的resizableImageWithCapInsets使用解析
    [翻译] RAReorderableLayout
    [翻译] ZLSwipeableView
    【转】php利用mkdir创建多级目录
    【转】用 PHP 内置函数 file_put_contents 写入文件
    【转】PHP 之 CURL 模拟登陆并获取数据
    【转】php curl 伪造IP来源的实例代码
    【转】POP3、SMTP和IMAP之间的区别和联系
  • 原文地址:https://www.cnblogs.com/ejiyuan/p/2556418.html
Copyright © 2011-2022 走看看