zoukankan      html  css  js  c++  java
  • 设计模式之工厂模式

    定义

    定义一个创建对象的接口,但由子类决定要实例的类是哪一个。工厂方法让类把实例推迟到子类。

    设计原则

    要依赖抽象,不要依赖具体的类:不能让高层组件依赖于底层组件,并且两者都应该依赖于抽象。

    指导方针

    • 变量不可以持有具体类的引用:如果使用new,就会持有具体类的引用。可以用工厂来避开这样的做法。
    • 不要让类派生自具体类:如果派生自具体类,你就会依赖具体类。派生自一个抽象。
    • 不要覆盖基类中已实现的方法:如果覆盖基类已实现的方法,那么你的基类就不是一个真正适合被继承的抽象。基类中所有实现的方法,应该由所有子类共享。

    抽象工厂模式

    提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定的具体类。

    第一次设计(识别变化)

    假设我们有一个披萨店,我们需要写代码来制造一些不同类型的披萨。
    下面来看看我们最开始的设计:

            Pizza orderPizza(string type)
            {
                Pizza pizza;
    
                if (type.Equals("cheese"))
                {
                    pizza = new CheesePizza();
                }
                else if (type.Equals("greek"))
                {
                    pizza = new GreekPizza();
                }
                else if (type.Equals("pepperoni"))
                {
                    pizza = new PepperoniPizza();
                }
                else
                {
                    pizza = new Pizza();
                }
                pizza.perpare();
                pizza.bake();
                pizza.cut();
                pizza.box();
                return pizza;
            }
    

    再这里我们根据type传入的类型来创建对应的pizza,但这里有一个问题,当我们需要修改一些pizza种类的时候,我们就必须要修改里面的代码。比如:不在提供GreekPizza的pizza,我们就必须删除创建GreekPizza的代码。这样就不符合我们的开放-关闭原则

    封装创建对象代码

    下面,我们将创建pizza对象代码封装到一个单独的对象中,由这个对象专职创建pizza。

        class SimplePizzaFactory
        {
            public Pizza createPizza(string type)
            {
                Pizza pizza = null;
    
                if (type.Equals("cheese"))
                {
                    pizza = new CheesePizza();
                }
                else if (type.Equals("greek"))
                {
                    pizza = new GreekPizza();
                }
                else if (type.Equals("pepperoni"))
                {
                    pizza = new PepperoniPizza();
                }
                else
                {
                    pizza = new Pizza();
                }
            }
        }
    

    重做PizzaStore类

    class PizzaStore
        {
            private SimplePizzaFactory factory;
    
            public PizzaStore(SimplePizzaFactory factory)
            {
                this.factory = factory;
            }
    
            Pizza orderPizza(string type)
            {
                Pizza pizza=null;
    
                pizza=factory.createPizza(type);
                pizza.perpare();
                pizza.bake();
                pizza.cut();
                pizza.box();
                return pizza;
            }
        }
    

    类图


    这种简单的工厂其实并不是一个设计模式,反而比较像是一种编程习惯。

    使用框架

    下面我们把createPizza的方法放回PizzaStore中,但是要把它设置成"抽象方法",然后为每个区域创建不同的PizzaStore子类。让每个子类各自决定如何制造披萨。

    public abstract class PizzaStore
        {
            //private SimplePizzaFactory factory;
    
            //public PizzaStore(SimplePizzaFactory factory)
            //{
            //    this.factory = factory;
            //}
    
            Pizza orderPizza(string type)
            {
                Pizza pizza = null;
    
               // factory.createPizza(type);
               //从工厂对象中移回PizzaStore中
                pizza = createPizza(type);
                pizza.perpare();
                pizza.bake();
                pizza.cut();
                pizza.box();
                return pizza;
            }
    
    
            //工厂对象移到这里
            public abstract Pizza createPizza(string type);
        }
        }
    

    在这里,orderPizza会对Pizza对象做许多的事情,但并不知道究竟是哪一种披萨,这里其实就是解耦。

    开一家披萨店

            public override Pizza createPizza(string type)
            {
                if (type.Equals("cheese"))
                {
                    return new CheesePizza();
                }
                //根据类型不同,创建其他对象
                return null;
            }
    

    工厂模式

    所有工厂模式都用来封装对象创建的。

    创建者类


    Creator类是一个抽象类,它定义了一个抽象的工厂方法,让子类实现此方法制造产品。
    子类可以利用createPrizza创建自己的产品。

    产品类

    对于上面的PizzaStore来说,Pizza就是产品。

    定义工厂方法模式

    工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推出到子类。

    依赖倒置原则

    当你直接实例化一个对象时,就是在依赖它的具体类。
    在代码里减少对于具体类依赖是件"好事"。这个原则就是依赖倒置原则——要依赖抽象,不要依赖具体类。
    不能让高层组件(由其他底层组件定义其行为的类)赖低层组件,不管高层还是底层,两者都应该依赖与抽象。
    上面示例应用工厂模式后类图:

    可以看到,高层组件(PizzaStore)和底层组件都依赖了Pizza抽象。

    几个指导方针帮助你遵循此原则

    • 变量不可以持有具体的引用
    • 不要让类派生自具体类
    • 不要覆盖基类中已经实现的方法
  • 相关阅读:
    Servlet 生命周期、工作原理(转)
    JVM的内存区域划分(转)
    Java的四个基本特性和对多态的理解
    单例模式和多例模式的区别(转)
    TCP/IP协议体系结构简介
    数据库优化性能
    存储过程的优缺点(转)
    ConurrentHashMap和Hashtable的区别
    XML和JSON优缺点
    HashMap和HashTable的区别
  • 原文地址:https://www.cnblogs.com/Tan-sir/p/8269292.html
Copyright © 2011-2022 走看看