方式设计04—工厂模式

模式设计04—工厂模式
模式设计04—工厂模式

来自《模式设计》的一个很好的例子来引入简单工厂模式,工厂模式,抽象工厂模式

这里有一家匹萨店,匹萨店可能是这样的:

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

}
当制作更多种类的匹萨时:

Pizza orderPizza(){
	Pizza pizza = new Pizza();
	
	if(type.equals("cheese")){
		
		pizza = new CheesePizza();
	
	}else if(type.equals("greek")){
	
		pizza = new GreekPizza();
	}else if(type.equals("pepperoni")){
	
		pizza = new PepperoniPizza();
	}

	pizza.prepare();
	pizza.bake();
	pizza.cut();
	pizza.box();
	return pizza;

}
问题出现了,当我们需要添加新的匹萨时,或者删除掉卖的不好的匹萨时,就会很麻烦。这时候应该将穿件对象封装到别处去,作法如下:

public class SimplePizzaFactory
{
	public Pizza createPizza(String type){
		Pizza pizza = null;

		if(type.equals("cheese")){
		
		pizza = new CheesePizza();
	
		}else if(type.equals("greek")){
	
		pizza = new GreekPizza();
		}else if(type.equals("pepperoni")){
	
		pizza = new PepperoniPizza();
		}
		return pizza;

	
	}
}
重做PizzaStore类:

public class PizzaStore
{
	SimplePizzaFactory factory;
	public PizzaStore(SimplePizzaFactory factory){
		this.factory = factory;
	}
	Pizza orderPizza(String type){
	Pizza pizza ;
	
	pizza = factory.createPizza(type);

	pizza.prepare();
	pizza.bake();
	pizza.cut();
	pizza.box();
	return pizza;

	}

}
这种封装方式便是简单工厂,简单工厂是一种编程习惯,而不是一种模式。
现在如果要在多处开辟新的匹萨分店的话,可能会这样:

NYPizzaFactory nyFactory = new NYPizzaFactory();
PizzaStore nyStore = new PizzaStore(nyFactory);
nyStore.orderPizza("Veggie");

但是如果不同分店的口味不一样呢,是否意味着就要进行大的修改,我们需要一种框架,把分店和创建匹萨捆绑在一起的同时又保持一定的弹性。

把createPizza()方法放回到PizzaStore中,不过把它设置成抽象方法,然后为每个分店创建一个PizzaStore的子类。

public abstract class PizzaStore
{
	public Pizza orderPizza(String type){
		Pizza pizza;
		pizza = createPizza(type);

		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();

		return pizza;

	
	}
	abstract Pizza createPizza(String type);
}
其中的一家分店,只用实现createPizza方法:

public class NYPizzaStore extends PizzaStore
{
	Pizza createPizza(String item){
		if(item.equals("cheese")){
			return new NYStyleCheesePizza();
		}else if(item.equals("greek")){
			return new NYStyleGreekPizza();
		}else if(item.equals("clam")){
			return new NYStyleClamPizza();
		}else
			return null;
	}
}
原本由一个对象负责所有具体类的实例化,现在通过对PizzaStore做了一些转变,变成由子类来负责实例化。工厂方法用来处理对象的创建,并将这样的行为封装在子类中。这样,客户程序中关于超类的代码就和子类对象创建代码解耦了。
abstract Product factoryMethod(String type);

工厂模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

设计原则tips:要依赖抽象,不要依赖具体类。
不应该让高层组件依赖低层组件,而且,不管高层或低层组件,“两者”都应该依赖于抽象。

抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。