抽象工厂模式定义
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
样例
上次的工厂方法模式使用的是披萨店的例子,为的是解决在各个不同的地区开的分店会做不同类型的披萨;
现在防止分店使用低价原料增加利润,损坏品牌,要确保每家店使用高质量的原料,所以打算使用生产原料的工厂;
但问题是每家分站使用的配料有可能不一样,如纽约的蛤蜊是新鲜的, 芝加哥的蛤蜊是冰冻的。
UML类图
注意由于太多,类图中的原料少画了2种:Pepperoni 与 Veggie,不影响大局。
代码
Dough.java
package com.jing.factory.abs;
public interface Dough {
public String toString();
}
DoughChicago.java
package com.jing.factory.abs;
public class DoughChicago implements Dough {
public String toString(){
return "Chicago Style Dough";
}
}
DoughNY.java
package com.jing.factory.abs;
public class DoughNY implements Dough {
public String toString(){
return "NY Style Dough";
}
}
Sauce.java
package com.jing.factory.abs;
public interface Sauce {
public String toString();
}
SauceChicago.java
package com.jing.factory.abs;
public class SauceChicago implements Sauce {
public String toString(){
return "Chicago Style Sauce";
}
}
SauceNY.java
package com.jing.factory.abs;
public class SauceNY implements Sauce {
public String toString(){
return "NY Style Sauce";
}
}
Cheese.java
package com.jing.factory.abs;
public interface Cheese {
public String toString();
}
CheeseChicago.java
package com.jing.factory.abs;
public class CheeseChicago implements Cheese {
public String toString(){
return "Chicago Style Cheese";
}
}
CheeseNY.java
package com.jing.factory.abs;
public class CheeseNY implements Cheese {
public String toString(){
return "NY Style Cheese";
}
}
Clams.java
package com.jing.factory.abs;
public interface Clams {
public String toString();
}
ClamsChicago.java
package com.jing.factory.abs;
public class ClamsChicago implements Clams {
public String toString(){
return "Chicago Style Clams";
}
}
ClamsNY.java
package com.jing.factory.abs;
public class ClamsNY implements Clams {
public String toString(){
return "NY Style Clams";
}
}
Pepperoni.java
package com.jing.factory.abs;
public interface Pepperoni {
public String toString();
}
PepperoniChicago.java
package com.jing.factory.abs;
public class PepperoniChicago implements Pepperoni {
public String toString(){
return "Chicago Style Pepperoni";
}
}
PepperoniNY.java
package com.jing.factory.abs;
public class PepperoniNY implements Pepperoni {
public String toString(){
return "NY Style Pepperoni";
}
}
Veggies.java
package com.jing.factory.abs;
public interface Veggies {
public String toString();
}
VeggiesGarlic.java
package com.jing.factory.abs;
public class VeggiesGarlic implements Veggies {
public String toString(){
return "Veggies Garlic";
}
}
VeggiesMushroom.java
package com.jing.factory.abs;
public class VeggiesMushroom implements Veggies {
public String toString(){
return "Veggies Mushroom";
}
}
VeggiesOlives.java
package com.jing.factory.abs;
public class VeggiesOlives implements Veggies {
public String toString(){
return "Veggies Olives";
}
}
VeggiesOnion.java
package com.jing.factory.abs;
public class VeggiesOnion implements Veggies {
public String toString(){
return "Veggies Onion";
}
}
VeggiesRedPepper.java
package com.jing.factory.abs;
public class VeggiesRedPepper implements Veggies {
public String toString(){
return "Veggies Red Pepper";
}
}
PizzaIngredientFactory.java
package com.jing.factory.abs;
public interface PizzaIngredientFactory {
public Dough createDough();
public Sauce createSauce();
public Cheese createCheese();
public Veggies[] createVeggies();
public Pepperoni createPepperoni();
public Clams createClam();
}
PizzaIngredientFactoryChicago.java
package com.jing.factory.abs;
public class PizzaIngredientFactoryChicago implements PizzaIngredientFactory {
public Dough createDough() {
// TODO Auto-generated method stub
return new DoughChicago();
}
public Sauce createSauce() {
// TODO Auto-generated method stub
return new SauceChicago();
}
public Cheese createCheese() {
// TODO Auto-generated method stub
return new CheeseChicago();
}
public Veggies[] createVeggies() {
// TODO Auto-generated method stub
Veggies veggies[] = {
new VeggiesOlives(),
new VeggiesMushroom(),
new VeggiesOnion()
};
return veggies;
}
public Pepperoni createPepperoni() {
// TODO Auto-generated method stub
return new PepperoniChicago();
}
public Clams createClam() {
// TODO Auto-generated method stub
return new ClamsChicago();
}
}
PizzaIngredientFactoryNY.java
package com.jing.factory.abs;
public class PizzaIngredientFactoryNY implements PizzaIngredientFactory {
public Dough createDough() {
// TODO Auto-generated method stub
return new DoughNY();
}
public Sauce createSauce() {
// TODO Auto-generated method stub
return new SauceNY();
}
public Cheese createCheese() {
// TODO Auto-generated method stub
return new CheeseNY();
}
public Veggies[] createVeggies() {
// TODO Auto-generated method stub
Veggies veggies[] = {
new VeggiesGarlic(),
new VeggiesRedPepper(),
new VeggiesMushroom()
};
return veggies;
}
public Pepperoni createPepperoni() {
// TODO Auto-generated method stub
return new PepperoniNY();
}
public Clams createClam() {
// TODO Auto-generated method stub
return null;
}
}
现在开始我们的披萨类
Pizza.java
package com.jing.factory.abs;
public abstract class Pizza {
protected String name;
Dough dough;
Sauce sauce;
Veggies veggies[];
Cheese cheese;
Pepperoni pepperoni;
Clams clam;
abstract void prepare();
void bake(){
System.out.println("Bake for 25 minutes at 350");
}
void cut(){
System.out.println("Cutting the pizza into diagonal slices");
}
void box(){
System.out.println("Place pizza in offical PizzaStore box");
}
void setName(String name){
this.name = name;
}
String getName(){
return name;
}
public String toString(){
StringBuffer result = new StringBuffer();
result.append("----- " +name +" --------- " + "\n");
if (dough != null){
result.append(dough);
result.append("\n");
}
if (sauce != null){
result.append(sauce);
result.append("\n");
}
if (cheese != null) {
result.append(cheese);
result.append("\n");
}
if (veggies != null){
for (int i = 0; i < veggies.length; i++){
result.append(veggies[i]);
if (i < veggies.length - 1){
result.append(", ");
}
}
result.append("\n");
}
if (clam != null){
result.append(clam);
result.append("\n");
}
if (pepperoni != null){
result.append(pepperoni);
result.append("\n");
}
return result.toString();
}
}
Pizza_Cheese.java
package com.jing.factory.abs;
public class Pizza_Cheese extends Pizza {
PizzaIngredientFactory ingredientFactory;
public Pizza_Cheese(PizzaIngredientFactory ingredientFactory){
this.ingredientFactory = ingredientFactory;
}
@Override
void prepare() {
// TODO Auto-generated method stub
System.out.println("Preparing " + name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createCheese();
}
}
Pizza_Clam.java
package com.jing.factory.abs;
public class Pizza_Clam extends Pizza {
PizzaIngredientFactory ingredientFactory;
public Pizza_Clam(PizzaIngredientFactory ingredientFactory){
this.ingredientFactory = ingredientFactory;
}
@Override
void prepare() {
// TODO Auto-generated method stub
System.out.println("Preparing " + name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createCheese();
clam = ingredientFactory.createClam();
}
}
Pizza_Pepperoni.java
package com.jing.factory.abs;
public class Pizza_Pepperoni extends Pizza {
PizzaIngredientFactory ingredientFactory;
public Pizza_Pepperoni(PizzaIngredientFactory ingredientFactory){
this.ingredientFactory = ingredientFactory;
}
@Override
void prepare() {
// TODO Auto-generated method stub
System.out.println("Preparing " + name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createCheese();
veggies = ingredientFactory.createVeggies();
pepperoni = ingredientFactory.createPepperoni();
}
}
Pizza_Veggie.java
package com.jing.factory.abs;
public class Pizza_Veggie extends Pizza {
PizzaIngredientFactory ingredientFactory;
public Pizza_Veggie(PizzaIngredientFactory ingredientFactory){
this.ingredientFactory = ingredientFactory;
}
public void prepare(){
System.out.println("Preparing " + name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createCheese();
veggies = ingredientFactory.createVeggies();
}
}
有了披萨后,我们应该开始写披萨店了
PizzaStore.java
package com.jing.factory.abs;
public abstract class PizzaStore {
protected abstract Pizza createPizza(String type);
public Pizza orderPizza(String type) {
Pizza pizza = createPizza(type);
System.out.println("-------- Making a " + pizza.getName() + " -----");
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
PizzaStoreChicago.java
package com.jing.factory.abs;
public class PizzaStoreChicago extends PizzaStore {
@Override
protected Pizza createPizza(String type) {
// TODO Auto-generated method stub
Pizza pizza = null;
PizzaIngredientFactory ingredientFactory = new PizzaIngredientFactoryChicago();
if (type.equals("cheese")){
pizza = new Pizza_Cheese(ingredientFactory);
pizza.setName("Chicago Style Cheese Pizza");
} else if (type.equals("veggie")){
pizza = new Pizza_Veggie(ingredientFactory);
pizza.setName("Chicago Style Veggie Pizza");
} else if (type.equals("clam")){
pizza = new Pizza_Clam(ingredientFactory);
pizza.setName("Chicago Style Clam Pizza");
} else if (type.equals("pepperoni")){
pizza = new Pizza_Pepperoni(ingredientFactory);
pizza.setName("Chicago Style Pepperoni Pizza");
}
return pizza;
}
}
PizzaStoreNY.java
package com.jing.factory.abs;
public class PizzaStoreNY extends PizzaStore {
@Override
protected Pizza createPizza(String type) {
// TODO Auto-generated method stub
Pizza pizza = null;
PizzaIngredientFactory ingredientFactory = new PizzaIngredientFactoryNY();
if (type.equals("cheese")){
pizza = new Pizza_Cheese(ingredientFactory);
pizza.setName("NY Style Cheese Pizza");
} else if (type.equals("veggie")){
pizza = new Pizza_Veggie(ingredientFactory);
pizza.setName("NY Style Veggie Pizza");
} else if (type.equals("clam")){
pizza = new Pizza_Clam(ingredientFactory);
pizza.setName("NY Style Clam Pizza");
} else if (type.equals("pepperoni")){
pizza = new Pizza_Pepperoni(ingredientFactory);
pizza.setName("NY Style Pepperoni Pizza");
}
return pizza;
}
}
现在开始写测试类
Test.java
package com.jing.factory.abs;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// 开一个纽约的披萨店
PizzaStore nyStore = new PizzaStoreNY();
// 开 一个芝加哥的披萨店
PizzaStore chicagoStore = new PizzaStoreChicago();
Pizza pizza = null;
// 开始订披萨
// 奶酪披萨
pizza = nyStore.orderPizza("cheese");
System.out.println("Customer A ordered a " + pizza + "\n");
pizza = chicagoStore.orderPizza("cheese");
System.out.println("Customer B ordered a " + pizza + "\n");
// 蛤蜊披萨
pizza = nyStore.orderPizza("clam");
System.out.println("Customer A ordered a " + pizza + "\n");
pizza = chicagoStore.orderPizza("clam");
System.out.println("Customer B ordered a " + pizza + "\n");
// 意式辣肠披萨
pizza = nyStore.orderPizza("pepperoni");
System.out.println("Customer A ordered a " + pizza + "\n");
pizza = chicagoStore.orderPizza("pepperoni");
System.out.println("Customer B ordered a " + pizza + "\n");
// 蔬菜披萨
pizza = nyStore.orderPizza("veggie");
System.out.println("Customer A ordered a " + pizza + "\n");
pizza = chicagoStore.orderPizza("veggie");
System.out.println("Customer B ordered a " + pizza + "\n");
}
}
输出
-------- Making a NY Style Cheese Pizza -----
Preparing NY Style Cheese Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in offical PizzaStore box
Customer A ordered a ----- NY Style Cheese Pizza ---------
NY Style Dough
NY Style Sauce
NY Style Cheese
-------- Making a Chicago Style Cheese Pizza -----
Preparing Chicago Style Cheese Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in offical PizzaStore box
Customer B ordered a ----- Chicago Style Cheese Pizza ---------
Chicago Style Dough
Chicago Style Sauce
Chicago Style Cheese
-------- Making a NY Style Clam Pizza -----
Preparing NY Style Clam Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in offical PizzaStore box
Customer A ordered a ----- NY Style Clam Pizza ---------
NY Style Dough
NY Style Sauce
NY Style Cheese
-------- Making a Chicago Style Clam Pizza -----
Preparing Chicago Style Clam Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in offical PizzaStore box
Customer B ordered a ----- Chicago Style Clam Pizza ---------
Chicago Style Dough
Chicago Style Sauce
Chicago Style Cheese
Chicago Style Clams
-------- Making a NY Style Pepperoni Pizza -----
Preparing NY Style Pepperoni Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in offical PizzaStore box
Customer A ordered a ----- NY Style Pepperoni Pizza ---------
NY Style Dough
NY Style Sauce
NY Style Cheese
Veggies Garlic, Veggies Red Pepper, Veggies Mushroom
NY Style Pepperoni
-------- Making a Chicago Style Pepperoni Pizza -----
Preparing Chicago Style Pepperoni Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in offical PizzaStore box
Customer B ordered a ----- Chicago Style Pepperoni Pizza ---------
Chicago Style Dough
Chicago Style Sauce
Chicago Style Cheese
Veggies Olives, Veggies Mushroom, Veggies Onion
Chicago Style Pepperoni
-------- Making a NY Style Veggie Pizza -----
Preparing NY Style Veggie Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in offical PizzaStore box
Customer A ordered a ----- NY Style Veggie Pizza ---------
NY Style Dough
NY Style Sauce
NY Style Cheese
Veggies Garlic, Veggies Red Pepper, Veggies Mushroom
-------- Making a Chicago Style Veggie Pizza -----
Preparing Chicago Style Veggie Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in offical PizzaStore box
Customer B ordered a ----- Chicago Style Veggie Pizza ---------
Chicago Style Dough
Chicago Style Sauce
Chicago Style Cheese
Veggies Olives, Veggies Mushroom, Veggies Onion