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,不用创建工厂实例。缺点:不能通过继承来改变创建方法的行为。

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

  • 相关阅读:
    sql 注入工具sqlmap的使用
    sql 注入手工实现二
    sql 注入手工实现
    虚拟机和docker简单对比
    22 MySQL--01mysql数据库的安装
    21 Linux的目录结构与目录管理
    20 Linux基础命令--01
    19 shell脚本--010awk
    18 shell脚本--009数组与字符串
    17 shell脚本--008函数
  • 原文地址:https://www.cnblogs.com/wpbxin/p/9065084.html
Copyright © 2011-2022 走看看