Factory

New创建对象

当使用new创建对象时,是在实例化一个具体的类,如:

Duck duck = new MallardDuck();

当有一群相关的具体类时,通常会这样写:

Duck duck;
if (picnic) {
    duck = new MallardDuck();
} else if (hunting) {
    duck = new DecoyDuck();
} else if (inBathTub) {
    duck = new RubberDuck();
}

这里有一些要实例化的具体类,究竟实例化哪个类,要在运行时根据条件决定,当看到这样的代码,一旦变化或扩展,就必须重新打开代码进行修改,这违背了“对扩展开放,对修改关闭”的原则。

认识变化的方面

假设有一家比萨店,作为店主人,你的代码可能这么写:

Pizza orderPizza() {
    Pizza pizza = new Pizza();
    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();
    return pizza;
}

但是你需要更多的比萨类型,所以必须增加一些代码:

Pizza orderPizza(String type) {
    Pizza pizza = new Pizza();
    if (typr.equals("cheese")) {
        pizza = new CheesePizza();
    } else if (typr.equals("greek")) {
        pizza = new GreekPizza();
    } else if (typr.equals("pepperoni")) {
        pizza = new PepperoniPizza();
    }
    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();
    return pizza;
}

但是,当你发现竞争者已在他们的菜单中加入一些流行风味的比萨:ClamPizza(蛤蜊比萨)、VeggiePizza(素食比萨),也要把他们加入进去,而最近GreekPizza(希腊比萨)卖的不好,需要将其从菜单中去掉,于是需要修改上述代码。很明显,如果需要实例化具体类,将使orderPizza()出问题,无法让orderPizza()对修改关闭;但是,我们已经知道哪些会改变,哪些不会改变。最好将创建比萨的代码(上述代码中if…else…部分)移到另一个对象(SimplePizzaFactory)中,由这个新对象专职创建比萨我们称这个新的对象为“工厂”,工厂(Factory)处理创建对象的细节。

建立一个简单比萨工厂

定义一个类,封装所有创建比萨对象。

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

重做PizzaStore类:

public class PizzaStore {
	SimplePizzaFactory factory;
	public PizzaStore(SimplePizzaFactory factory) {
		this.factory = factory;
	}
	public Pizza orderPizza(String type) {
		// 这里把new操作符替换成工厂对象的创建方法
		Pizza pizza = factory.createPizza(type);
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza;
	}
}

定义简单工厂

简单工厂其实不是一个设计模式,而像是一种“编程习惯”。简单工厂用来为我们“暖身”,接下来是两个重量级的模式(工厂方法和抽象工厂),它们都是工厂。先来看看新的比萨店类图。

QQ图片20160426072949
posted @ 2016-04-25 06:40  devotion987  阅读(205)  评论(0编辑  收藏  举报