工厂模式
工厂模式是用来封装对象的创建。
简单工厂
简单工厂只是一编程习惯。
比如说下面的一段代码, 为了实现根据不同的客户需求制作不同的pizza。
Pizza orderPizza(String type){
Pizza pizza;
//可能会改的地方
if("cheese".equals(type)){
pizza = new CheesePizza();
}else if("greek".equals(type)){
pizza = new GreekPizza();
}else if("pepperoni".equals(type)){
pizza = new PepperoniPizza();
}
//一般不会改
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
将可能会改的地方抽出来,使用简单工厂可以这么写:
public class PizzaStore(){
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory){
this.factory = factory;
}
public Pizza orderPizza(){
Pizza pizza = factory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
public class SimplePizzaFactory{
public Pizza createPizza(String type){
Pizza pizza;
if("cheese".equals(type)){
pizza = new CheesePizza();
}else if("greek".equals(type)){
pizza = new GreekPizza();
}else if("pepperoni".equals(type)){
pizza = new PepperoniPizza();
}
return pizza;
}
}
使用简单工厂的好处是:
- 代码可以复用,生成pizza的方法
createPizza()
可以被其他类调用。 - 当生成pizza的方法改动时,比如说有新的pizza类型,只需改动
createPizza()
的内部实现,一次修改,多处生效。
工厂方法模式
工厂方法模式是另外一种封装对象的创建的模式。
它通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。
比如说下面一段代码:
有一个抽象创建者类PizzaStore
,类里有一个抽象方法createPizza()
, 让子类实现此方法制造产品。抽象创建者只是提供了一个接口,他并不需要知道具体在制造什么产品
子类是具体创建者。子类可以创建自己风格的产品。比如纽约风味和芝加哥风味的芝士披萨(虽然我也不知道他们有什么不同,就比如广东口味的麻辣烫和湖南口味的麻辣烫吧)
public abstract class PizzaStore{
public Pizza orderPizza(String type){
Pizza pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
//工厂方法 - 定义成抽象方法,由子类决定具体实现
abstract Pizza createPizza(String type);
}
public class NYStylePizzaStore(){
public Pizza createPizza(String type){
Pizza pizza;
if("cheese".equals(type)){
pizza = new NYStyleCheesePizza();
}else if("greek".equals(type)){
pizza = new NYStyleGreekPizza();
}else if("pepperoni".equals(type)){
pizza = new NYStylePepperoniPizza();
}
return pizza;
}
}
public class ChicagoStylePizzaStore(){
public Pizza createPizza(String type){
Pizza pizza;
if("cheese".equals(type)){
pizza = new ChicagoStyleCheesePizza();
}else if("greek".equals(type)){
pizza = new ChicagoStyleGreekPizza();
}else if("pepperoni".equals(type)){
pizza = new ChicagoStylePepperoniPizza();
}
return pizza;
}
}
实现类图
工厂方法不一定是抽象的,也可以在抽象创建者类中实现一个默认的工厂方法,然后又子类决定是否要覆盖。