一:相关定义
这里的工厂模式分为三种:简单工厂模式、工厂模式和抽象工厂模式;
简单工厂模式:其实不算是一种模式,而是一种编程习惯,这里就不定义了,因为我也没找到
工厂模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
二:相关类图和示例
简单工厂(直接上示例图):
下面是关键代码:
public class PizzaStore{
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;
}
//其他方法
}
示例图中和代码都挺清楚了,这里就不赘述啦。
工厂模式类图:
Creator中定义abstract Product factoryMethod(String type)抽象方法,由子类来实现;这样,定义的不同的子类工厂,将返回不同的创建的Product。具体看下面示例:
工厂模式示例:
我们来看看这个关于Pizza(比萨)的工厂模式核心代码:
//PizzaStore的子类在createPizza()方法中,处理对象的实例化。
public abstract class PizzaStore{
public Pizza orderPizza(String type){
Pizza pizza;
pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
//此方法如同一个工厂
protected abstract Pizza createPizza(String type);
}
上述为抽象的创建者(Creator),在orderPizza方法中定义了烘培Pizza的流程(使用模板模式),而将创建不同Pizza的责任交给了子类来实现;例如:
public class NYPizzaStore extends PizzaStore{
Pizza createPizza(String item){
if(item.equals("cheese")){
return new NYStyleCheesePizza();
}else if(item.equals("veggie")){
return new NYStyleVeggiePizza();
}
}
}
public class ChicagoPizzaStore extends PizzaStore{
Pizza createPizza(String item){
if(item.equals("cheese")){
return new ChicagoStyleCheesePizza();
}else if(item.equals("veggie")){
return new ChicagoStyleVeggiePizza();
}
}
}
这里,关于Pizza的定义我们就进行省略了。下面来看如何使用:
//建立两个不同的店,分别进行下订单
PizzaStore nyStore = new NYPizzaStore();
PizzaStore chicagoStore = new ChicagoPizzaStore();
Pizza pizza = nyStore.orderPizza("cheese");
System.out.println("Order a "+pizza.getName());
pizza = chicagoStore.orderPizza("cheese");
System.out.println("Order a "+pizza.getName());
这样,我们就实现了在各个地域中比萨店自己的独特风味(纽约比萨饼薄,芝加哥比萨饼厚等)。
在这个示例中,我们看看工厂模式起到的作用:Pizza在纽约(NY)和芝加哥(Chicago)都有分店。为了确保质量,制作Pizza的工序固定(prepare-box),且都有cheese(奶酪风味)和Veggie(素食风味)等不同口味;但是NY和Chicago两地的Pizza店对于一种风味(如cheese)的Pizza也都有自己的特色(如微辣和变态辣),这时,不能使用简单工厂模式来创建Pizza对象了,应该交由各地的工厂来创建自己独特的风味Pizza,如此便可使用工厂模式。在上图,真正的创建Pizza的步骤交给了下面的不同的子类实现,父类仅仅确保了制作Pizza的流程。
抽象工厂模式类图:
结合下面的例子来进行理解:
抽象工厂模式示例(摘自Headfirst 设计模式):
先看看这个例子中,使用抽象工厂模式的目的是什么:在上面例子中,工厂方法使得各地都可以生产自己独特风味的Pizza,但是为了保证质量,生产Pizza的原料我们想要保证都是自己的原料,这样,需要各地都使用我们运输给他们的一组原料来创建Pizza,这样就用到了抽象工厂模式,下面看代码:
先看Pizza(前面懒,就没写,到这里了没法避免)
public abstract class Pizza{
String name;//名字 //每个Pizza都持有一组在准备时会用到的原料
Dough dough;//面团
Sauce sauce;//酱汁
Veggies[] veggies;//蔬菜
Cheese cheese;//奶酪
Pepperoni peperoni;//意大利腊肠
Clams clam;//蛤
//将prepare设置成抽象(原来不是哦)。在此方法中,我们收集Pizza的所需的原料(来自我们的原料工厂:固定的一组原料)
abstract void prepare;
void bake(){
System.out.println("bake for 25 minutes at 350");//烤
}
void cut(){
//切
}
void box(){
//装盒
}
void setName(String name){
this.name = name;
}
String getName(){
return name;
}
public String toString{
//打印比萨
}
}
再看我们的抽象工厂接口PizzaIngredientFactory:
public interface PizzaIngerdFactory{
public Dough createDough();
public Sauce createSauce();
public Cheese createCheese();
public Veggies[] createVeggies();
public Pepperoni createPepperoni();
public Clam createClam();
}
下面是纽约(NY)的原料工厂:
//实现工厂接口
public class NYPizzaIngredientFactory implements PizzaIngredientFactory{
//对于原料家族的每一种原料,我们都提供了纽约(NY)版本
public Dough createDough(){
return new ThinCrustDough();
}
public Sauce createSauce(){
return new MarinaraSauce();
}
public Cheese createCheese(){
return new ReggianoCheese();
}
public Veggies[] createVeggies{
Veggies[] veggies = {new Garlic(), new Onion()};
return veggies;
}
public Pepperoni createPepperoni(){
return new SlicedPepperoni();
}
public Clams createClam(){
return new FreshClams();
}
}
上面,就实现了我们的纽约(NY)原料工厂(芝加哥chicago的Factory类似),来看看 如何使用吧:
public class cheesePizza extends Pizza{
PizzaIngredientFactory ingredientFactory;
//每个Pizza需要从构造函数取得一个工厂,用以提供原料
public CheesePizza(PizzaIngredientFactory ingredientFactory){
this.ingredientFactory = ingredientFactory;
}
void prepare(){
System.out.println("Prepareing "+name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createCheese();
}
}
这样我们创建Pizza时,就可以这样:
public class NYPizzaStore extends PizzaStore{
protected Pizza createPizza(String item){
Pizza pizza = null;
PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
if("cheese".equals(item)){
pizza = new CheesePizza(ingredientFactory);
pizza.setName("NY Style Cheese Pizza");
}else if("veggies".equals(item)){
pizza = new VeggiePizza(ingredientFactory);
pizza.setName("NY Style Veggie Pizza");
}
return pizza;
}
这里,我们使用组合的方式,传递一个原料工厂,然后创建一整个家族的原料对象,这就是抽象工厂模式了。
参考书籍:《head first 设计模式》《大话设计模式》