这篇文章总结的主要是工厂方法和抽象工厂,顺带简单工厂这种编程习惯
一、简单工厂
简单工厂并不算是一种设计模式,他更像一种编程习惯,并没有严格的遵守开放关闭原则,而且他仅仅只是把要改变的部分跟不变的部分分离开,但是把具体产品的创造过程封装起来,客户端程序猿就不需要直接操作一堆具体子类,在知道最少的情况下达到目标,不必考虑这个类是怎么被创建出来的,降低了程序的耦合。
我们看看wiki百科的一段话:普通的工厂方法模式通常伴随着对象的具体类型与工厂具体类型的一一对应,客户端代码根据需要选择合适的具体类型工厂使用。然而,这种选择可能包含复杂的逻辑。这时,可以创建一个单一的工厂类,用以包含这种选择逻辑,根据参数的不同选择实现不同的具体对象。这个工厂类不需要由每个具体产品实现一个自己的具体的工厂类,所以可以将工厂方法设置为静态方法。 而且,工厂方法封装了对象的创建过程。如果创建过程非常复杂(比如依赖于配置文件或用户输入),工厂方法就非常有用了。
假设Pizza为产品抽象,它下层有各种具体子类Pizza,当客人预定Pizza的时候,提供一个类图:
看起来就像是SimpleFactory托管了创建过程
public abstract class Pizza {
public void prepare(){System.out.println("正在准备Pizza...");}
public void bake(){System.out.println("正在烘培...");}
public void cut(){System.out.println("正在切片...");}
public void box(){System.out.println("正在装箱...");}
}
public class PepperoniPizza extends Pizza {
@Override
public void prepare() {System.out.println("正在准备PepperoniPizza...");}
@Override
public void bake() {System.out.println("正在烘培PepperoniPizza...");}
@Override
public void cut() {System.out.println("正在切片PepperoniPizza...");}
@Override
public void box() {System.out.println("正在装箱PepperoniPizza...");}
}
其他Pizza的子类省略,基本一样
public class SimplePizzaFactory {
public Pizza createPizza(String type){
Pizza pizza = null;
if(type.equals("cheese")){pizza = new CheesePizza();
}else if(type.equals("pepperoni")){pizza = new PepperoniPizza();
}else if(type.equals("clam")){pizza = new ClamPizza();
}else if(type.equals("veggie")){pizza = new VeggiePizza();}
return pizza;
}
}
工厂把创建过程封装起来,当客户端需要调用的时候,直接使用工厂:
public class PizzaStore {
private SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory){
this.factory = factory;
}
public Pizza orderPizza(String type){
Pizza pizza;
pizza = factory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
能注意到的是,即使他仅仅是把创建的代码搬到了另外一个地方(其实实质也是这样子),看上去问题并没有解决,但需要考虑到加入创建的逻辑非常复杂,而我们需要给客户程序员提供方便,这样的方法就很有力量了,一般来说简单工厂是声明为静态的,这样子的缺点就是不能通过继承来改变创建方法的行为
优点:
1、责任分割,客户端程序猿直接被免除了创建产品的责任,决定在什么时候创建子类
2、对客户端来说,减少了记忆创建产品逻辑过程的记忆负担
3、通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性
缺点:
1、除了无法继承,但是逻辑复杂,一旦不能正常工作,整个系统都要受到影响
2、逻辑过于复杂,产品过多的时候,产品维护的花销较大
所以,当我们考虑使用简单工厂的时候,必须要考虑到它的执行逻辑、产品数目规模是不大的
二、工厂方法(Factory Method)
首先看看工厂方法的定义&