《Head.First设计模式》的学习笔记(6)--抽象工厂模式



 意图:
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

结构:

《Head.First设计模式》的学习笔记(6)--抽象工厂模式

实例:还是以Pizza店为例,现在pizza需要进行需要不同的原料,例如添加cheese,sauce等原料,重新扩展的pizza为:

 

package headfirst.factory.pizzaaf;

public abstract class Pizza {
	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 official 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();
	}
}

 

 然后我们定义一个抽象工厂PizzaIngredientFactory:

package headfirst.factory.pizzaaf;

public interface PizzaIngredientFactory {
 
	public Dough createDough();
	public Sauce createSauce();
	public Cheese createCheese();
	public Veggies[] createVeggies();
	public Pepperoni createPepperoni();
	public Clams createClam();
 
}

 

 

 继续我们假设有一个纽约的原料工厂,精于大蒜番茄酱料,Reggiano干酪,新鲜蛤蜊........

package headfirst.factory.pizzaaf;

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
 
	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(), new Mushroom(), new RedPepper() };
		return veggies;
	}
 
	public Pepperoni createPepperoni() {
		return new SlicedPepperoni();
	}

	public Clams createClam() {
		return new FreshClams();
	}
}
 

 

然后我们现在创建一个奶酪pizza

 

 

package headfirst.factory.pizzaaf;

public class CheesePizza extends Pizza {
	PizzaIngredientFactory ingredientFactory;
 
	public CheesePizza(PizzaIngredientFactory ingredientFactory) {
		this.ingredientFactory = ingredientFactory;
	}
 
	void prepare() {
		System.out.println("Preparing " + name);
		dough = ingredientFactory.createDough();
		sauce = ingredientFactory.createSauce();
		cheese = ingredientFactory.createCheese();
	}
}

 

最后我们来看这个纽约的pizza店,怎么用纽约的原料工厂创建出具有纽约风味的cheese的pizza:

package headfirst.factory.pizzaaf;

public class NYPizzaStore extends PizzaStore {
 
	protected Pizza createPizza(String item) {
		Pizza pizza = null;
		PizzaIngredientFactory ingredientFactory = 
			new NYPizzaIngredientFactory();
 
		if (item.equals("cheese")) {
  
			pizza = new CheesePizza(ingredientFactory);
			pizza.setName("New York Style Cheese Pizza");
  
		} else if (item.equals("veggie")) {
 
			pizza = new VeggiePizza(ingredientFactory);
			pizza.setName("New York Style Veggie Pizza");
 
		} else if (item.equals("clam")) {
 
			pizza = new ClamPizza(ingredientFactory);
			pizza.setName("New York Style Clam Pizza");
 
		} else if (item.equals("pepperoni")) {

			pizza = new PepperoniPizza(ingredientFactory);
			pizza.setName("New York Style Pepperoni Pizza");
 
		} 
		return pizza;
	}
}

 

最后我们来看最后的类图:



《Head.First设计模式》的学习笔记(6)--抽象工厂模式
 
 抽象工厂和工厂方法的一些联系:

1.工厂方法潜伏在抽象工厂模式之下,例如上面我们说的createDough(),createSource()方法,这些其实都在被继承的时候,然后来实现实例化的。

2.抽象工厂和工厂方法都是创建对象,工厂方法是“继承”(把对象的创建委托给子类,子类实现工厂方法来创建对象),抽象工厂通过对象的组合(对象的创建被实现在工厂接口暴露出来的方法中),抽象工厂产品家族和想让制造的相关的产品集合起来,而工厂方法可以让实例通过子类进行决定。

3.提醒我们随时要针对接口编程,而不是对实现编程。

缺点:

如果要增加相应的产品,相应的继承子类也要进行修改。繁琐。

 

 

你可能感兴趣的:(抽象工厂模式)