工厂模式
每次用new来实例化对象的时候,都是实例化具体的类,不是面向接口编程,而是实现;代码绑着具体类会导致代码更脆弱,更缺乏弹性,初始化也经常造成耦合的问题。
假设现在有家披萨Pizza 店,有很多披萨比如pizzaA、pizzaB、pizzaC、pizzaD,产生披萨的类一开始可能会这样写
Pizza orderPizza(String type){
// Pizza 抽象类 ABCDE 是实现子类
Pizza pizza;
if(type.equals("A")){
pizza = new pizzaA();
}else if(type.equals("B")){
pizza = new pizzaB();
}else if(type.equals("C")){
pizza = new pizzaC();
}else if(type.equals("D")){
pizza = new pizzaD();
}else if(type.equals("E")){
pizza = new pizzaE();
}
// 披萨的其他加工步骤
pizza.prepare();
pizza.bake(); //烘烤
pizza.cut(); //切片
pizza.box(); //装盒
return pizza;
}
这个设计显然违背了 封闭——开放原则,如果pizza 种类增多,或者要去除一些不受欢迎的披萨,就必须修改orderPizza ,而这都是没有对变化封闭的原因。于是我们把创建pizza 那边代码搬移到简单的工厂SimplePizzaFactory
public class SimplePizzaFactory{
public Pizza createPizza(String type){
// Pizza 抽象类 ABCDE 是实现子类
Pizza pizza = null;
if(type.equals("A")){
pizza = new pizzaA();
}else if(type.equals("B")){
pizza = new pizzaB();
}else if(type.equals("C")){
pizza = new pizzaC();
}else if(type.equals("D")){
pizza = new pizzaD();
}else if(type.equals("E")){
pizza = new pizzaE();
}
return pizza;
}
}
// 修改 orderPizza
public class PizzaStore{
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory){
this.factory = factory;
}
public Pizza orderPizza(String type){
Pizza pizza;
pizza = factory.createPizza(type);
// pizza 的其他方法
}
}
我们来看一下引入这个简单工厂的类图设计,
上面只是一个简单的工厂设计,如果披萨店变得很多了怎么办,createPizza应该生产哪家披萨店的披萨呢?我们可以把pizzaStore 设计成一个抽象类
public abstract Class PizzaStore {
public Pizza orderPizza(String type){
Pizza pizza;
pizza = createPizza(type);
pizza.prepare();
pizza.bake();
// pizza 其他制作方法
return pizza
}
// createPiza 决定生产那个店的披萨,父类的orderPizza 和子类createPizza 解耦
abstract Pizza createPizza(String type);
}
//披萨店A
pubic class storeAPizzaStore extends PizzaStore{
Pizza createPizza(String type){
if(type.equals("A")){
return new storeApizzaA();
}else if(type.equals("B")){
return new storeApizzaB();
}else if(type.equals("C")){
return new storeApizzaC();
}else if(type.equals("D")){
return new storeApizzaD();
}
}
}
在看看工厂方法的定义
abstract Product factoryMethod(String type)
工厂方法用来处理对象的创建,并将这样的行为封装在子类中。这样,客户程序中关于超类的代码就和子类对象创建代码解耦了。
- 工厂方法是抽象,依赖子类实现对象创建
- 工厂方法必须返回一个产品
- 工厂方法将客户代码和实际创建具体产品的代码分隔开
- 参数看情况是否需要
这样披萨的制作过程代码就是
pizzaStore storeA = new storeAPizzaStore();
Pizaa storeAPizzaB = storeA.orderPizza('B');
pizzaStore storeB = new storeBPizzaStore();
Pizaa storeBPizzaB = storeB.orderPizza('B');
再来看看利用该复杂工厂的设计类图,
欢迎大家给我留言,提建议,指出错误,一起讨论学习技术的感受!