有关抽象工厂文章可先看:http://quicker.iteye.com/blog/575183
在http://quicker.iteye.com/blog/607944 中我们使用工厂方法给不同地区的比萨店生产出相应口味的比萨。不过当时我们考虑的各个店同一种比萨的口味和用来生产的原料是一样的。比如纽约的芝士比萨和北京的芝士比萨口味与生产所用原料是一样的 。
但是实际上各个地域不同,同一名称的比萨,口味可能不同,生产的原料也可能不同。
于是公司总部决定自己建立一个原料生产基础,给不同地域的比萨加盟店运送相应的原料。
好了,结合http://quicker.iteye.com/blog/575183中电脑的生产示例,生产的都是电脑,生产电脑都要用到CPU和RAM,但是在中国生产的电脑可能用的是龙芯,RAM也是自己的品牌,而在美国用的CPU和RAM就不是同一种。但不管怎么样他们最终都将用来生产各自的电脑,只不过使用的原料不一样。。
正确的理解应是:所有的产品都使用相同的组件制造而成,但是每个区域的这些组件都有不同的实现
在比萨店的示例里面,我们使用了工厂方法。
但是我们不难发现:Pizza,NYCheesePizza,ChicagoCheesePizza这几个类实际上是相似的。他们的区别只是不同地域的pizza所使用的原料不同,那么我们就利用抽象工厂来实现。。
抽象工厂定义:抽象工厂提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
具体实现:
原料类:
package com.lwf.disign.learn.abstractfactory.cheese;
public interface Cheese {
}
package com.lwf.disign.learn.abstractfactory.cheese;
public class ChicagoCheese implements Cheese {
}
package com.lwf.disign.learn.abstractfactory.cheese;
public class NYCheese implements Cheese {
}
package com.lwf.disign.learn.abstractfactory.daugh;
public interface Dough {
}
package com.lwf.disign.learn.abstractfactory.daugh;
public class NYDough implements Dough {
}
package com.lwf.disign.learn.abstractfactory.daugh;
public class ChicagoDough implements Dough {
}
package com.lwf.disign.learn.abstractfactory.sauce;
public interface Sauce {
}
package com.lwf.disign.learn.abstractfactory.sauce;
public class NYSauce implements Sauce{
}
package com.lwf.disign.learn.abstractfactory.sauce;
public class ChicagoSauce implements Sauce{
}
原料工厂类:
package com.lwf.disign.learn.abstractfactory.ingreditfactory;
import com.lwf.disign.learn.abstractfactory.cheese.Cheese;
import com.lwf.disign.learn.abstractfactory.daugh.Dough;
import com.lwf.disign.learn.abstractfactory.sauce.Sauce;
public interface PizzaIngredientFactory {
public Dough createDough();
public Sauce createSauce();
public Cheese createCheese();
}
package com.lwf.disign.learn.abstractfactory.ingreditfactory;
import com.lwf.disign.learn.abstractfactory.cheese.Cheese;
import com.lwf.disign.learn.abstractfactory.cheese.NYCheese;
import com.lwf.disign.learn.abstractfactory.daugh.Dough;
import com.lwf.disign.learn.abstractfactory.daugh.NYDough;
import com.lwf.disign.learn.abstractfactory.sauce.NYSauce;
import com.lwf.disign.learn.abstractfactory.sauce.Sauce;
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
public Cheese createCheese() {
return new NYCheese();
}
public Dough createDough() {
return new NYDough();
}
public Sauce createSauce() {
return new NYSauce();
}
}
package com.lwf.disign.learn.abstractfactory.ingreditfactory;
import com.lwf.disign.learn.abstractfactory.cheese.Cheese;
import com.lwf.disign.learn.abstractfactory.cheese.ChicagoCheese;
import com.lwf.disign.learn.abstractfactory.daugh.ChicagoDough;
import com.lwf.disign.learn.abstractfactory.daugh.Dough;
import com.lwf.disign.learn.abstractfactory.sauce.ChicagoSauce;
import com.lwf.disign.learn.abstractfactory.sauce.Sauce;
public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {
public Cheese createCheese() {
return new ChicagoCheese();
}
public Dough createDough() {
return new ChicagoDough();
}
public Sauce createSauce() {
return new ChicagoSauce();
}
}
Pizza类:
package com.lwf.disign.learn.abstractfactory.pizza;
import com.lwf.disign.learn.abstractfactory.cheese.Cheese;
import com.lwf.disign.learn.abstractfactory.daugh.Dough;
import com.lwf.disign.learn.abstractfactory.sauce.Sauce;
public abstract class Pizza {
String name; //名称
Dough dough; //面团类型
Sauce sauce; //酱料类型
Cheese cheese;
public abstract void prepare();
public void bake() {
System.out.println("Bake for 25 minutes at 350");
}
public void cut() {
System.out.println("Cutting the pizza into diagonal slices");
}
public void box() {
System.out.println("Pizza in offical PizzaStrore box");
}
public String getName(){
return name;
}
}
package com.lwf.disign.learn.abstractfactory.pizza;
import com.lwf.disign.learn.abstractfactory.ingreditfactory.PizzaIngredientFactory;
public class CheesePizza extends Pizza {
private PizzaIngredientFactory pizzaIngredientFactory;
public CheesePizza(PizzaIngredientFactory pizzaIngredientFactory){
this.pizzaIngredientFactory = pizzaIngredientFactory;
}
public void prepare(){
dough = pizzaIngredientFactory.createDough();
sauce = pizzaIngredientFactory.createSauce();
cheese =pizzaIngredientFactory.createCheese();
}
public void cut(){
System.out.println("cut it into CheesePizza slices");
}
}
package com.lwf.disign.learn.abstractfactory.pizza;
import com.lwf.disign.learn.abstractfactory.ingreditfactory.PizzaIngredientFactory;
public class VegglePizza extends Pizza {
private PizzaIngredientFactory pizzaIngredientFactory;
public VegglePizza(PizzaIngredientFactory pizzaIngredientFactory){
this.pizzaIngredientFactory = pizzaIngredientFactory;
}
public void prepare(){
dough = pizzaIngredientFactory.createDough();
sauce = pizzaIngredientFactory.createSauce();
cheese =pizzaIngredientFactory.createCheese();
}
public void cut(){
System.out.println("cut it into VegglePizza slices");
}
}
PizzaStore类:
package com.lwf.disign.learn.abstractfactory.pzstore;
import com.lwf.disign.learn.abstractfactory.pizza.Pizza;
public abstract class PizzaStore {
public final Pizza orderPizza(String type){
Pizza pizza;
pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
abstract Pizza createPizza(String type);
}
package com.lwf.disign.learn.abstractfactory.pzstore;
import com.lwf.disign.learn.abstractfactory.ingreditfactory.NYPizzaIngredientFactory;
import com.lwf.disign.learn.abstractfactory.ingreditfactory.PizzaIngredientFactory;
import com.lwf.disign.learn.abstractfactory.pizza.CheesePizza;
import com.lwf.disign.learn.abstractfactory.pizza.Pizza;
import com.lwf.disign.learn.abstractfactory.pizza.VegglePizza;
public class NYPizzaStore extends PizzaStore {
Pizza createPizza(String type) {
Pizza pizza = null;
PizzaIngredientFactory pizzaIngredientFactory = new NYPizzaIngredientFactory();
if(type.equals("cheese")){
pizza = new CheesePizza(pizzaIngredientFactory);
}else if(type.equals("veggle")){
pizza = new VegglePizza(pizzaIngredientFactory);
}
return pizza;
}
}
package com.lwf.disign.learn.abstractfactory.pzstore;
import com.lwf.disign.learn.abstractfactory.ingreditfactory.ChicagoPizzaIngredientFactory;
import com.lwf.disign.learn.abstractfactory.pizza.CheesePizza;
import com.lwf.disign.learn.abstractfactory.pizza.Pizza;
import com.lwf.disign.learn.abstractfactory.pizza.VegglePizza;
public class ChicagoPizzaStore extends PizzaStore {
Pizza createPizza(String type) {
Pizza pizza = null;
ChicagoPizzaIngredientFactory chicagoPizzaIngredientFactory = new ChicagoPizzaIngredientFactory();
if(type.equals("cheese")){
pizza = new CheesePizza(chicagoPizzaIngredientFactory);
}else if(type.equals("veggle")){
pizza = new VegglePizza(chicagoPizzaIngredientFactory);
}
return pizza;
}
}
测试类:
package com.lwf.disign.learn.abstractfactory.pzstore;
import com.lwf.disign.learn.abstractfactory.pizza.Pizza;
public class PizzaStoreTest {
public static void main(String[] args) {
PizzaStore pizzaStore = new NYPizzaStore();
Pizza pizza = pizzaStore.orderPizza("cheese");
print(pizza.getName());
pizza = pizzaStore.orderPizza("veggle");
print(pizza.getName());
pizzaStore = new ChicagoPizzaStore();
pizza = pizzaStore.orderPizza("cheese");
print(pizza.getName());
pizza = pizzaStore.orderPizza("veggle");
print(pizza.getName());
}
public static void print(String name){
System.out.println(name);
System.out.println("-------------------------------------------------------------");
}
}
我们再看看抽象工厂的UML图。
看看pizzastore的抽象工厂图。
我们使用了工厂方法与抽象工厂实现了比萨店。
那么工厂方法与抽象工厂有什么区别呢。
他们都用来创建对象,工厂方法使用继承;而抽象工厂则使用对象组合。这意味着使用工厂方法就要扩展一个类,并覆盖它的工厂方法。
工厂方法只负责将客户从具体类型中解藕。
当你需要创建产品家族和想让制造的相关产品集合起来时,你可以使用抽象工厂。
如果你目前还不知道将来需要实例化哪些具体类时,你可以使用工厂方法。