为什么会有工厂模式
Why?
早期程序代码设计时,在代码内部嵌套了大量的具体类对象,代码的业务逻辑部分与依赖对象部分往往放在一起,使得程序的耦合度极高,每当增加新的功能时,往往需要打开内部代码进行修改,导致后期的扩展与维护异常困难。
例如:
Pizza order(String type){
//-----------------------------------
Pizza pizza;
if(type.equal("cheese")){
pizza = new CheesePizza();
}else if(type.equal("pepperoni")){
pizza = new PepperoniPizza();
}else if(type.equal("clam")){
pizza = new ClamPizza();
}else if(type.equal("veggie")){
pizza = new VeggiePizza();
}
/*
* 这份代码没有对修改关闭,随着时间的推移,披萨选项可能会发生变化,如果披萨店改变其披萨供应,我们就得打开这份代码来修改(这也是问题的根源)
*/
//------------------------------------------
pizza.prepare();
pizza.bake();
pizza.cut();
}
一旦你的代码内嵌了大量的具体类对象,当加入新的具体类对象时(新增功能),你将不得不再次打开代码,对代码进行修改;这是在自找麻烦,严重违反了对修改关闭的设计原则。
What to do?
1、我们可以把那一部分变化的部分给它拿出来封装到一个抽象数据类型(类)中
2、本类声明一个该抽象数据类型的变量,从该变量所指向的对象中获得想要的对象
3、后续的对象扩展可以在该抽象数据类型中修改(当然还不够完善,因为还是没有对修改关闭)
披萨商店类
public class PizzaStore{
SimplePizzaFactory factory;
public PizzaStore(){
}
public void setFactory(SimplePizzaFactory factory){
this.factory = factory;
}
public Pizza orderPizza(String type){
Pizza pizza;
pizza = factory.create(type);
pizza.prepare();
pizza.bake();
pizza.cut();
}
}
披萨工厂类
class SimplePizzaFactory{
public Pizza create(String type){
if(type.equal("cheese")){
return new CheesePizza();
}else if(type.equal("pepperoni")){
return new PepperoniPizza();
}else if(type.equal("clam")){
return new ClamPizza();
}
}
}
披萨类
public class CheesePizza{}
public class PepperoniPizza{}
public class ClamPizza{}
这样的好处是SimplePizzaFactory可以有很多客户,如果有其他商家想要获得披萨的当前描述和价格可以直接声明一个披萨工厂变量,而不需要在自己类的内部嵌套大量的实现类对象,可以直接从工厂中拿到想要的对象;通过把披萨对象的创建封装进一个类中,当实现变化时,我们只需要改变这个工厂类即可而不需要改变每个商家类。把具体实例化的的代码部分从商家类中移除了
总结
工厂模式的特点:
- 负责某一类对象的创建
- 将对象的创建与业务逻辑代码分离开来