工厂模式:工厂方法

还是利用比萨店的例子,我们来看看一般工厂模式:

如果比萨店有许多加盟店,并且这些加盟店必须严格按照总部的要求生产比萨。

比如烘烤、切片、打包的方式。但允许加盟店根据各地的特色制作比萨。这要如何实现?

我们可以定义一个抽象类PizzaStore,这个类中有两个方法

orderPizza和createPizza,其中createPizza是抽象的。由子类来具体实现。

在orderPizza方法中定义比萨店的框架。

package com.headfirst.chapter4;

public abstract class PizzaStore {
	public Pizza orderPizza(String type){
		Pizza pizza;
		pizza = createPizza(type);
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza;
	}
	abstract Pizza createPizza(String type);//工厂方法
}

纽约和芝加哥的PizzaStore继承这个抽象类

package com.headfirst.chapter4;

public class NYStylePizzaStore extends PizzaStore {

	Pizza createPizza(String type) {
		Pizza pizza = null;
		if(type.equals("cheese")){
			pizza = new NYStyleCheesePizza();
		}else if(type.equals("pepperoni")){
			pizza = new NYStylePepperoniPizza();
		}
		return pizza;
	}

}
package com.headfirst.chapter4;

public class ChicagoStylePizzaStore extends PizzaStore{
	
	Pizza createPizza(String type) {
		Pizza pizza = null;
		if(type.equals("cheese")){
			pizza = new ChicagoStyleCheesePizza();
		}else if(type.equals("pepperoni")){
			pizza = new ChicagoStylePepperoniPizza();
		}
		return pizza;
	}
}

在这两个子类中依据传入参数的类型来决定具体需要生产的比萨。

同样:Pizza类也定义为抽象的

package com.headfirst.chapter4;

import java.util.ArrayList;
import java.util.List;

public abstract class Pizza {
	String name;
	String dough;
	String sauce;
	List topping = new ArrayList();
	void prepare(){
		System.out.println("Preparing "+name);
		System.out.println("Tossing dough...");
		System.out.println("Adding sauce...");
		for (int i = 0; i < topping.size(); i++) {
			System.out.println(""+topping.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 offical PizzaStore box");
		System.out.println();
	}
	public String getName(){
		return name;
	}
}

 以下为各城市加盟店具体生产的比萨

package com.headfirst.chapter4;

public class NYStyleCheesePizza extends Pizza {

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

}
package com.headfirst.chapter4;

public class NYStylePepperoniPizza extends Pizza {

	public NYStylePepperoniPizza() {
		name = "NY Styel Pepperon Pizza";
		dough ="NY Styel pepperon dough";
		sauce = "pepperon sauce";
		topping.add("pepperon topping");
	}

}
package com.headfirst.chapter4;

public class ChicagoStyleCheesePizza extends Pizza{

	public ChicagoStyleCheesePizza() {
		name = "Chicago Style Deep Dish Cheese Pizza";
		dough = "Extra Thick Crust Dough";
		sauce = "Plum Tomato Sauce";
		topping.add("Shredded Mozzarella Cheese");
	}
	void cut() {
		System.out.println("Cutting the pizza into square slice");
	}

}
package com.headfirst.chapter4;

public class ChicagoStylePepperoniPizza extends Pizza {

	public ChicagoStylePepperoniPizza() {
		name = "Chicago Style Pepperoni Pizza";
		dough = "Chicago Style Pepperoni dough";
		sauce = "Chicago Style Pepperoni sauce";
		topping.add("Chicago Style topping");
	}

}

最后写一个测试类:

package com.headfirst.chapter4;

public class PizzaTestDrive {
	public static void main(String[] args) {
		PizzaStore nyPizzaStore = new NYStylePizzaStore();
		PizzaStore chicagoPizzaStore = new ChicagoStylePizzaStore();
		
		nyPizzaStore.orderPizza("cheese");
		chicagoPizzaStore.orderPizza("cheese");
	}
}

所有的工厂模式都用来封闭对象的创建,工厂方法模式通过让子类决定该创建的对象是什么,来达到将对象创建的过程封闭的目的。

定义工厂方法模式:

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的是哪一个。工厂方法让类把实例化推迟到子类。

上图中的Creator是一个类,它实现了所有操纵产品的方法 ,但不实现工厂方法

Creator所有的子类都必须实现这个抽象的factoryMethod()方法。

ConcreteCreator实现了factoryMethod()方法以制造实现产品。

简单工厂与工厂方法的差异:

简单工厂把全部的事情在一个地方都处理完了,而工厂方法却是创建一个框架,让子类决定要如何实现。

使用工厂方法有什么好处?

1,避免代码重复

2,方便后期维护

3,针对接口编程,使代码更有弹性,方便未来扩展。

猜你喜欢

转载自mynote.iteye.com/blog/1538227