工厂 > 简单工厂

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

简单工厂就是把各种类型的实例的创建封装在“工厂”里,使用者作为工厂的客户,不需要自己创建实例,只需要使用工厂提供的接口获得即可。

以《Head First设计模式》中的预定Pizza场景为例。先来看一下工厂的产品:Pizza实体类

/** * 工厂的抽象产品类Pizza,包含所有类型Pizza公共的内容 */
public abstract class Pizza {
    public void bake() {
        System.out.println("bake...");
    }

    public void cut() {
        System.out.println("cut...");
    }
}

产生Pizza的简单工厂定义:

/** *@Description:简单工厂 */
public class SimplePizzaFactory {

    public Pizza createPizza(String type) {
        if ("cheese".equals(type)) {
            return new CheesePizza();
        } else if ("clam".equals(type)) {
            return new ClamPizza();
        } else if ("veggie".equals(type)) {
            return new VeggiePizza();
        }
        return null;
    }
}

这里有一个常见的技巧:把createPizza定义为static类型,好处是不需要通过实例化SimplePizzaFactory的方式调用createPizza方法,缺点是不能通过继承来改变创建方法的行为。

这里createPizza方法接收的参数是String类型,其实使用提前定义好的常量或者enum枚举类型更好一些。看一个使用枚举的示例:

public enum ExcelExportTemplate {
    lotBuyExcel(1, "海外基金购买份额模板"), lotRansomExcel(2, "海外基金赎回份额模板");

    public int value;
    public String desc;

    private ExcelExportTemplate(int value, String desc) {
        this.value = value;
        this.desc = desc;
    }
}

使用这个枚举的工厂示例:

public class ExcelExportMapFactory {

    public static LinkedHashMap<String,ExcelColumn> createExcelMap(ExcelExportTemplate template){
        LinkedHashMap<String,ExcelColumn> map = null;
        //海外基金购买份额模板
        if(ExcelExportTemplate.lotBuyExcel == template){ 
            ...
        }
        //海外基金赎回份额模板
        else if(ExcelExportTemplate.lotRansomExcel == template){
            ...
        }
        return map;
    }
}

再回到订购Pizza的场景中,看一下Pizza工厂的客户–Pizza商店

package factory.simplefactory;

/** *@Description:工厂的客户 - Pizza商店 *@Author:tony *@Since:2016年2月24日 */
public class PizzaStore {

    SimplePizzaFactory factory;

    public PizzaStore(SimplePizzaFactory factory){
        this.factory = factory;
    }

    public Pizza orderPizza(String type){
        Pizza pizza = factory.createPizza(type);
        pizza.bake();
        pizza.cut();
        return pizza;
    }
}

使用场景: 预定Pizza

package factory.simplefactory;

public class SimpleFactoryTest {
    public static void main(String[] args) {
        SimplePizzaFactory factory = new SimplePizzaFactory();
        PizzaStore store = new PizzaStore(factory);
        store.orderPizza("cheese");
    }
}

在整个预定Pizza的流程(orderPizza方法)中,只有制作具体的Pizza实例是变化的,其余的像烘烤和切割流程都是不变的,把变化的部分从中剥离出来,封装为简单工厂根据类型new具体的Pizza实现类,将来如果增加或减少Pizza的种类,PizzaStore是不需要改动的,仅改动本来就是变化部分的工厂类即可。保持PizzaStore不改动,也符合了“对扩展开放,对修改关闭”的原则。简单工厂是把全部的事情(创建各种Pizza对象)在一个地方都处理完了,然后供PizzaStore客户使用。

参考资料:《Head First设计模式》

你可能感兴趣的:(工厂 > 简单工厂)