• 设计模式------工厂方法模式


    工厂方法模式定义一个接口用于创建对象,让子类决定哪一个类实例.工厂方法,使一类延迟到其子类的实例.

    角色:

    1.抽象工厂(Creator)角色:

    是工厂方法模式的核心,与应用程序无关。

    不论什么在模式中创建对象的工厂类必须实现这个接口。


    2.详细工厂(ConcreteCreator)角色:

    这是实现抽象工厂接口的详细工厂类。包括与应用程序密切相关的逻辑,而且受到应用程序调用以创建产品对象。


    3.抽象产品(Product)角色:

    工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共有的接口。


    4.详细产品(ConcreteProduct)角色:

    这个角色实现了抽象产品角色所定义的接口。

    某详细产品有专门的详细工厂创建,它们之间往往一一相应。


    结构图:



    适用情况:

    1.对于某个产品,调用者清楚地知道应该使用哪个详细工厂服务,实例化该详细工厂,生产出详细的产品来。

    2.仅仅是须要一种产品,而不想知道也不须要知道到底是哪个工厂为生产的,即终于选用哪个详细工厂的决定权在生产者一方,它们依据当前系统的情况来实例化一个详细的工厂返回给使用者,而这个决策过程对于使用者来说是透明的。


    工厂方法模式VS简单工厂模式:

     以下以编写“计算器”的小程序为例,对照学习工厂方法模式。


    1.简单工厂模式:


    简单工厂类:


    工厂类中包括了必要的逻辑推断。依据client的选择条件动态实例化相关的类。对于client来说,去除了与详细产品的依赖。当添加其它算法时,须要在工厂类中加case分支条件,这样就违背了“开放-封闭原则”。

    简单工厂模式链接


    2.工厂方法模式:


     
    工厂方法模式对简单工厂模式进行了抽象,将简单工厂的内部逻辑推断移到了client中。它有一个抽象的Factory类(能够是抽象类和接口)。这个类将不再负责详细的产品生产,仅仅制定一些规范,详细的生产工作由其子类去完毕。


    工厂方法模式实现:

    运算类:

    class Operation
        {
            private double _numberA = 0;
            private double _numberB = 0;
    
            public double NumberA
            {
                get { return _numberA; }
                set { _numberA = value; }
            }
    
            public double NumberB
            {
                get { return _numberB; }
                set { _numberB = value; }
            }
    
            /// 得到运算结果        
            
            public virtual double GetResult()
            {
                double result = 0;
                return result;
            }
        }

    加法类:

     class OperationAdd : Operation
        {
            public override double GetResult()
            {
                double result = 0;
                result = NumberA + NumberB;
                return result;
            }
        }

    减法类:

    class OperationSub : Operation
        {
           ...
        }

    乘法类:

     class OperationMul : Operation
        {
            ...
        }

    除法类:

     class OperationDiv : Operation
        {
            public override double GetResult()
            {
                double result = 0;
                if (NumberB == 0)
                    throw new Exception("除数不能为0。");
                result = NumberA / NumberB;
                return result;
            }
        }

    依据依赖倒转原则。把工厂类抽象出一个接口,这个接口具有一个创建抽象产品的工厂方法,全部生产详细类的工厂,都要实现这个接口。

    工厂类

     interface IFactory
        {
            Operation CreateOperation();
        }

    加法工厂:

     // 专门负责生产“+”的工厂
        
        class AddFactory : IFactory
        {
            public Operation CreateOperation()
            {
                return new OperationAdd();
            }
        }

    减法工厂:

     // 专门负责生产“-”的工厂
        
        class SubFactory : IFactory
        {
            public Operation CreateOperation()
            {
                return new OperationSub();
            }
        }

    乘法工厂:...

    除法工厂:...

    client:

      static void Main(string[] args)
            {
                IFactory operFactory = new AddFactory();//进行其它运算时,仅仅需在此改动就可以
                Operation oper = operFactory.CreateOperation();
                oper.NumberA = 1;
                oper.NumberB = 2;
                double result=oper.GetResult();
    
                Console.WriteLine(result);
    
                Console.Read();
            }

    最后在控制台窗体显示得数“3”。


    分析:

    核心工厂类不再负责产品的创建,成为一个抽象工厂角色,使一个类的实例化延迟到其子类,这样进一步抽象化使得工厂方法模式能够使系统在不改动详细工厂角色的情况下引进新的产品。当添加新的算法时,不需更改原有的工厂类,仅仅需添加此功能的运算类和对应的详细生产工厂,仅仅对扩展开放,对改动关闭,弥补了简单工厂的不足,仍保持封装对象创建过程的长处,减少了客户程序与产品对象的耦合。工厂方法的缺点就是每添加一个产品,须要添加这个产品工厂的类,利用反射技术能够进行完好。


    小编寄语:通过写博客。加深了理解,沉淀了知识。欢迎大家指点,我们共同进步。

     

     


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    215. Kth Largest Element in an Array
    214. Shortest Palindrome
    213. House Robber II
    212. Word Search II
    210 Course ScheduleII
    209. Minimum Size Subarray Sum
    208. Implement Trie (Prefix Tree)
    207. Course Schedule
    206. Reverse Linked List
    sql 开发经验
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4912410.html
Copyright © 2020-2023  润新知