zoukankan      html  css  js  c++  java
  • 浅析设计模式(一)——简单工厂方法

    简单工厂方法(Simple-Factory,非设计模式,创建型)

     注:部分内容参考自《Head First设计模式》和GoF《设计模式:可复用面向对象软件的基础》

     本文的结构:

    一、简单工厂方法的定义

      简单工厂方法把变化的部分(即创建对象的细节)封装起来,即通过工厂类(Factory)来处理创建对象的细节。

      首先需要说明的是:简单工厂方法不是一种设计模式,它更像是一种编程习惯。个人理解,这种处理方式把创建对象的细节进行了简单的封装,单独进行管理,不再与其他操作直接关联,使之得到解耦,便于维护。工厂类的职责也比较单一和明确,不会有冗余设计。

    二、示例

    注:以下代码可参考《Head First设计模式》,或者【我的github】。

      例如:要创建不同类型的Pizza,我们不在PizzaStore的方法中直接根据Pizza类型来创建Pizza,而是把这些创建的代码通过工厂(factory)封装起来,由factory直接负责和维护。这样PizzaStore与Pizza的创建便分离开了,后续如果有新增加的Pizza只要维护factory即可。

    1、PizzaStore类

      其中的pizza = factory.createPizza(type);便是由工厂类进行实际的处理。

      试想下,如果把创建Pizza对象的代码直接写在PizzaStore中,后续每次新增或者删除一类Pizza,都需要对PizzaStore进行修改以适应最新的场景。实际上PizzaStore的其他流程并没有发生化,需要变化的只是Pizza的种类罢了。如果以现在的方式来维护的话,处理Pizza的工作全部由工厂类来处理,PizzaStore完全不用关心实际的创建过程,只需要按照正常的流程即可。

    package com.designpatterns.creationalpatterns.simplefactory;
    
    
    /**
     * 
     * Reference : Head-First-Design-Patterns
     *
     */
    public class PizzaStore {
        /**
         * 工厂类,负责处理创建对象的具体细节
         */
        SimplePizzaFactory factory;
         
        public PizzaStore(SimplePizzaFactory factory) { 
            this.factory = factory;
        }
        public void setFactory(SimplePizzaFactory factory) {
            this.factory = factory;
        }
     
        public Pizza orderPizza(String type) {
            Pizza pizza;
    
            /**
             * <p>
             * 这里原本是工厂方法中创建Pizza的过程,被factory进行了封装
             * <p>
             * Here we create the pizza with factory.
             */
            pizza = factory.createPizza(type);
     
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
    
            return pizza;
        }
    }

      2、工厂类Factory

      封装实际的创建对象工作。

     1 package com.designpatterns.creationalpatterns.simplefactory;
     2 
     3 
     4 /**
     5  * <p>
     6  * 简单工厂方法:
     7  * <p>
     8  * 把变化的部分(创建对象)封装起来,即通过工厂(factory)来处理创建对象的细节。
     9  * <p>
    10  * 简单工厂方法不是一种设计模式,而是一种编程习惯。
    11  * 
    12  * Reference : Head-First-Design-Patterns
    13  *
    14  */
    15 
    16 public class SimplePizzaFactory {
    17     
    18     /**
    19      * 根据实际类型创建相应的对象
    20      * @param type
    21      * @return
    22      */
    23     public Pizza createPizza(String type) {
    24         Pizza pizza = null;
    25 
    26         if (type.equals("cheese")) {
    27             pizza = new CheesePizza();
    28         } else if (type.equals("pepperoni")) {
    29             pizza = new PepperoniPizza();
    30         } else if (type.equals("clam")) {
    31             pizza = new ClamPizza();
    32         } else if (type.equals("veggie")) {
    33             pizza = new VeggiePizza();
    34         }
    35         return pizza;
    36     }
    37 }

     3、测试类

      简单地创建了PizzaStore和工厂类,PizzaStore实际上使用工厂类进行Pizza对象的创建。

     1 package com.designpatterns.creationalpatterns.simplefactory;
     2 
     3 /**
     4  * 
     5  * Reference : Head-First-Design-Patterns
     6  *
     7  */
     8 
     9 public class PizzaTestApp {
    10     public static void main(String[] args) {
    11         //创建工厂
    12         SimplePizzaFactory factory = new SimplePizzaFactory();
    13         PizzaStore pizzaStore = new PizzaStore(factory);
    14         
    15         //order a pizza
    16         Pizza pizza = pizzaStore.orderPizza("clam");
    17         System.out.println("We ordered a " + pizza.getName() + "
    ");
    18         System.out.println(pizza);
    19         
    20         //change the pizza type
    21         pizza = pizzaStore.orderPizza("veggie");
    22         System.out.println("We ordered a " + pizza.getName() + "
    ");
    23         System.out.println(pizza);
    24         
    25     }
    26 }

     简单工厂方法有以下几个变种:

    1. 变种1:添加多个创建的方法,负责不同对象的创建。
    2. 变种2:静态工厂方法,把方法设置为static,不用创建工厂实例。缺点:不能通过继承来改变创建方法的行为。

      以上便是简单工厂方法的大致介绍。后面要介绍的工厂方法模式、抽象工厂模式也有相通之处。它们在工厂类的基础上进行了不同的抽象和扩展,以满足相应的场景。

  • 相关阅读:
    HDU4529 郑厂长系列故事——N骑士问题 —— 状压DP
    POJ1185 炮兵阵地 —— 状压DP
    BZOJ1415 聪聪和可可 —— 期望 记忆化搜索
    TopCoder SRM420 Div1 RedIsGood —— 期望
    LightOJ
    LightOJ
    后缀数组小结
    URAL
    POJ3581 Sequence —— 后缀数组
    hdu 5269 ZYB loves Xor I
  • 原文地址:https://www.cnblogs.com/wpbxin/p/9065084.html
Copyright © 2011-2022 走看看