设计模式笔记04-工厂模式(二)

2014-11-23 23:41:32 · 作者: · 浏览: 8
解耦了。 * 1、工厂方法是抽象的,所以依赖子类来处理对象的创建; * 2、工厂方法必须返回一个产品。超类中定义的方法,通常使用到工厂方法的返回值; * 3、工厂方法将客户(也就是超类中的代码,例如orderPizza())和实际创建具体产品的代码分离 */ abstract Pizza createPizza(String item); 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; } }

刚刚忽略了一件重要的事,Pizza本身。
public abstract class Pizza {
	//每个Pizza都具有名称、面团类型、酱料类型、一套酢料
	String name;
	String dough;
	String sauce;
	ArrayList toppings = new ArrayList();
 
	void prepare() {
		System.out.println("Preparing " + name);
		System.out.println("Tossing dough...");
		System.out.println("Adding sauce...");
		System.out.println("Adding toppings: ");
		for (int i = 0; i < toppings.size(); i++) {
			System.out.println("   " + toppings.get(i));
		}
	}
  
	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");
	}
 
	public String getName() {
		return name;
	}

	public String toString() {
		StringBuffer display = new StringBuffer();
		display.append("---- " + name + " ----\n");
		display.append(dough + "\n");
		display.append(sauce + "\n");
		for (int i = 0; i < toppings.size(); i++) {
			display.append((String )toppings.get(i) + "\n");
		}
		return display.toString();
	}
}

以下罗列一些具体的pizza子类
public class NYStyleCheesePizza extends Pizza {

	public NYStyleCheesePizza() { 
		name = "NY Style Sauce and Cheese Pizza";
		dough = "Thin Crust Dough";
		sauce = "Marinara Sauce";
 
		toppings.add("Grated Reggiano Cheese");
	}
}

public class ChicagoStyleCheesePizza extends Pizza {

	public ChicagoStyleCheesePizza() { 
		name = "Chicago Style Deep Dish Cheese Pizza";
		dough = "Extra Thick Crust Dough";
		sauce = "Plum Tomato Sauce";
 
		toppings.add("Shredded Mozzarella Cheese");
	}
 
	//这个Pizza覆盖了cut()方法,将Pizza切成了正方形
	void cut() {
		System.out.println("Cutting the pizza into square slices");
	}
}

具体的PizzaStroe类
public class NYPizzaStore extends PizzaStore {

	Pizza createPizza(String item) {
		if (item.equals("cheese")) {
			return new NYStyleCheesePizza();
		} else if (item.equals("veggie")) {
			return new NYStyleVeggiePizza();
		} else if (item.equals("clam")) {
			return new NYStyleClamPizza();
		} else if (item.equals("pepperoni")) {
			return new NYStylePepperoniPizza();
		} else return null;
	}
}

测试类
public class PizzaTestDrive {
 
	public static void main(String[] args) {
		PizzaStore nyStore = new NYPizzaStore();
		PizzaStore chicagoStore = new ChicagoPizzaStore();
 
		Pizza pizza = nyStore.orderPizza("cheese");
		System.out.println("Ethan ordered a " + pizza.getName() + "\n");
 
		pizza = chicagoStore.orderPizza("cheese");
		System.out.println("Joel ordered a " + pizza.getName() + "\n");
}


认识工厂方法模式的时刻终于到了: 所有工厂模式都用来封装对象的创建。 工厂方法模式(Factory Method Pattern)通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。 让我们来看下有哪些组成元素: 1、 创建者类(creator):PizzaStore、NYPizzaStore、ChicagoPizzaStore PizzaStore是抽象创建者类,它定义了一个抽象的工厂方法,让子类实现此方法制造产品。创建者通常会包含依赖于抽象产品的代码,而这些抽象产品由子类制造。创建者不需要真的知道在制造哪种具体产品。 NYPizzaStore、ChicagoPizzaStore是具体创建者类,createPizza()方法是真正的工厂方法,用来制造产品。因为每个加盟店都有自己的PizzaStore子类,所以可以利用实现createPizza()方法创建自己风味的Pizza。 2、 产品类:Pizza以及各个加盟店的产品类(Pizza子类) 平行的类层级:我们已经看到,将一个orderPizza()方法和一个工厂方法联合起来,就可以成为一个框架。除此之外,工厂方法将生产知识封装进各个创建者,这样的做法,也可以被视为一个框架。
定义工厂方法模式:工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。 根据上面PizzaStore的分工我们不难理解,首先有两个很重要父类,FactoryCreator(抽象接口)和Product(产品),通过抽象工厂方法让子类实现制造产品(继承于Product)。
简单工厂和工厂方法模式的区别: 简单工厂把全部事情,都在一个地方处理完了。然而工厂方法却是创建一个框架,让子类决定要如何实现。比方说,在工厂方法中,orderPizza()方法提供了一般的框架,以便创建Pizza,orderPizza()方法依赖工厂方法创建具体类,并制造出实际的Pizza。可通过继承PizzaStore类,决定实际制造出的Pizza是什么。简单工厂的做法,可以将对象的创建封装起来,但是简单工厂不具备工厂方法的弹性,因为简单工厂不能变更正在创建的产品。

2.6 抽象工厂模式


代码里减少对于具体类的依赖是件”好事“。