zoukankan      html  css  js  c++  java
  • 设计模式学习笔记二:简单工厂模式

    含义:

    从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。(摘自百度百科)。

    另外,在Head First中说简单工厂不是一个设计模式,而像一种编程习惯。我觉得这个说的比较准确。在一个方法体中,当有大量的case when 或者 if else的时候,有“洁癖的”开发人员会进行一下简单的重构将这部分逻辑提取出来,封装成一个方法(放在当前类或一个新建的类中)。这样可以增加可读性,非常建议新人使用这种技巧,个人觉得一个方法体代码行数超过300行看着就比较累了。当封装完后发现方法体依然远远超出300行,那说明系统架构设计存在问题(一家之言)。

        下面描述一个场景:

            有一家电子商务公司从事酒店、机票、旅游、度假等业务。对不同业务线的订单流程我们都进行统一处理。 创建订单、订单支付、通知客人、订单最终处理。

            下面看不使用简单工厂模式的实现:

     

    /* 
     * OrderProcessCenter.java 1.0 2014/08/11 
     *  
     * 声明:欢迎转载,请注明出处。 
     *  
     */  
    package com.liushijie.simple_factory;
    /**
     * 订单中心,负责对所有类型的订单进行操作
     * @author array7
     *
     */
    public class OrderProcessCenter {
        public Order OrderFlow(String type) {
            Order order = null;
            if ("air".equals(type)) {    // 航空组订单
                order = new AirOrder();
            } else if ("hotel".equals(type)) {    // 酒店组订单
                order = new HotelOrder();
            } else if ("ticket".equals(type)) {    // 门票组订单
                order = new TicketOrder();
            } else if ("xxx".equals(type)) {    // ...
                // TODO: some thing
            } else if ("yyy".equals(type)) {
                // TODO: some thing
            } else if ("zzz".equals(type)) {
                // TODO: some thing
            } else if ("123".equals(type)) {
                // TODO: some thing
            }
            order.pay();
            order.notifyCustomer();
            order.finish();
            return order;
        }
    }


    通过以上代码我们可以很容易发现,假设我们要维护增改订单组必须要修改那一串逻辑判断,很明显这不符合开放原则 - 对修改关闭。我们知道要改什么,知道怎么改,那就完全可以提取出来。 

     同时,在业务逻辑中,创建订单本身就是一个比较专一的功能,我们完全可以将其提取出来统一进行创建操作。若要新增订单只要在专职创建订单的方法中修改即可。修改后的代码如下: 

    /* 
     * OrderProcessCenter.java 1.0 2014/08/11 
     *  
     * 声明:欢迎转载,请注明出处。 
     *  
     */  
    
    package com.array7.simple_factory;
    /**
     * 订单中心,负责对所有类型的订单进行操作
     * @author array7
     *
     */
    public class OrderProcessCenter {
        public Order OrderFlow(String type) {
            Order order = new SimpleOrderFactory().createOrder(type);
            order.pay();
            order.notifyCustomer();
            order.finish();
            return order;
        }
    }
    
    package com.array7.simple_factory;
    
    public class SimpleOrderFactory {
        public Order createOrder(String type) {
            Order order = null;
            if ("air".equals(type)) {
                order = new AirOrder();
            } else if ("hotel".equals(type)) {
                order = new HotelOrder();
            } else if ("ticket".equals(type)) {
                order = new TicketOrder();
            } else if ("xxx".equals(type)) {
                // TODO: some thing
            } else if ("yyy".equals(type)) {
                // TODO: some thing
            } else if ("zzz".equals(type)) {
                // TODO: some thing
            } else if ("123".equals(type)) {
                // TODO: some thing
            }
            return order;
        }
    }

    提取完后又发现,这种方式还有一个优点:

    创建订单成为了单独的实现,我们可以开放给我其他的调用方进行使用,实现了代码的复用。比如调用方生成订单,我们进行订单的后续跟进。 

  • 相关阅读:
    C++11中静态局部变量初始化的线程安全性
    213. 打家劫舍 II
    cas解决aba相关问题
    socket[可读可写异常]3种条件的发生
    linux信号处理 (信号产生 信号阻塞 信号集)
    vim set paste解决粘贴乱序乱码问题
    174. 地下城游戏
    208. 实现 Trie (前缀树) 和 面试题 17.13. 恢复空格
    Centos安装和卸载docker
    Go语言轻量级框架-Gin与入门小案例MySQL增删查改
  • 原文地址:https://www.cnblogs.com/liushijie/p/4712927.html
Copyright © 2011-2022 走看看