模式设计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:要依赖抽象,不要依赖具体类。
不应该让高层组件依赖低层组件,而且,不管高层或低层组件,“两者”都应该依赖于抽象。
抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。