您的位置:首页 > 其它

设计模式学习--工厂模式(Factory Pattern)

2013-05-30 13:28 639 查看

设计模式学习--工厂模式(Factory Pattern)

2013年5月30日 设计模式学习记录

什么是工厂模式?

工厂模式可分为以下三种类型,需要根据不同需求来决定使用哪一种模式:
1. 简单工厂(不是真正意义上的设计模式)
2. 工厂方法(定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类实例化推迟到子类)
3. 抽象工厂(提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类)

面向对象原则:

多用组合,少用继承
针对接口编程,不针对实现编程
为交互对象之间的松耦合而努力
类应该对扩展开放,对修改关闭
依赖抽象,不是依赖具体类(新的原则)

要点:

1. 所有的工厂都是用来封装对象的创建。
2. 简单工厂,虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体类解耦。
3. 工厂方法使用继承:把对象的创建委托给子类子类实现工厂方法来创建对象。
4. 抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露出来的方法中。
5. 所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合。
6. 工厂方法允许类将实例化延迟到子类进行。
7. 抽象工厂创建相关的对象家族,而不需要依赖它们的具体类。
8. 依赖倒置原则,指导我们避免依赖具体类型,而要尽量依赖抽象。
9. 工厂是很有威力的技巧,帮助我们针对抽象编程,而不要针对具体类编程。

工厂模式应用实例:比萨店

简单工厂实现

看看UML的类图



项目结构:



源代码:

/Pizza.java

package pizzas;

import java.util.ArrayList;
/***
 *	抽象pizza类
 * @author wwj
 *
 */
abstract public class Pizza {
	String name;
	String dough;
	String sauce;
	ArrayList toppings = new ArrayList();
	
	
	public String getName() {
		return name;
	}

	@Override
	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();
	}

	//准备
	public void prepare() {
		System.out.println("Preparing " + name);
	}

	//烘烤
	public void bake() {
		System.out.println("Baking " + name);
	}

	//切片
	public void cut() {
		System.out.println("Cutting " + name);
	}

	//装箱
	public void box() {
		System.out.println("Boxing " + name);
	}
	
	
}


package pizzas;
/**
 * 2013/5/25
 * @author wwj
 *
 */
public class CheesePizza extends Pizza {
	@SuppressWarnings("unchecked")
	public CheesePizza() {
		name = "Cheese Pizza";
		dough = "Regular Crust";
		sauce = "Marinara Pizza Sauce";
		toppings.add("Fresh Mozzarella");
		toppings.add("Parmesan");
	}
}


package pizzas;
/**
 * 2013/5/25
 * @author wwj
 *
 */
public class ClamPizza extends Pizza {
	@SuppressWarnings("unchecked")
	public ClamPizza() {
		name = "Clam Pizza";
		dough = "Thin crust";
		sauce = "White garlic sauce";
		toppings.add("Clams");
		toppings.add("Grated parmesan cheese");
	}
}


package pizzas;
/**
 * 2013/5/25
 * @author wwj
 *
 */
public class PepperoniPizza extends Pizza {
	@SuppressWarnings("unchecked")
	public PepperoniPizza() {
		name = "Pepperoni Pizza";
		dough = "Crust";
		sauce = "Marinara sauce";
		toppings.add("Sliced Pepperoni");
		toppings.add("Sliced Onion");
		toppings.add("Grated parmesan cheese");
	}
}


package pizzas;
/**
 * 素食pizza
 * @author wwj
 *
 */
public class VegglePizza extends Pizza {
	@SuppressWarnings("unchecked")
	public VegglePizza(){
		name = "Veggie Pizza";
		dough = "Crust";
		sauce = "Marinara sauce";
		toppings.add("Shredded mozzarella");
		toppings.add("Grated parmesan");
		toppings.add("Diced onion");
		toppings.add("Sliced mushrooms");
		toppings.add("Sliced red pepper");
		toppings.add("Sliced black olives");
	}
}


/SimplePizzaFactory.java

package pizzas;
/**
 * 2013/5/27
 * @author wwj
 * 简单工厂方法
 */
public class SimplePizzaFactory {
	public Pizza createPizza(String type) {
		Pizza pizza = null;
		
		if(type.equals("cheese")) {
			pizza = new CheesePizza();
		} else if(type.equals("pepperoni")) {
			pizza = new PepperoniPizza();
		} else if(type.equals("clam")) {
			pizza = new ClamPizza();
		} else if(type.equals("veggie")) {
			pizza = new VegglePizza();
		}
		return pizza;
	}
}


/PizzaStore

package pizzas;

public class PizzaStore {
	SimplePizzaFactory factory;

	public PizzaStore(SimplePizzaFactory factory) {
		this.factory = factory;
	}
	
	public Pizza orderPizza(String type) {
		Pizza pizza;
		
		pizza = factory.createPizza(type);
		
		pizza.prepare();	//准备
		pizza.bake();		//烘烤
		pizza.cut();		//切片
		pizza.box();		//装盒
		return pizza;
	}
}


/PizzaTestDriver

package pizzas;
/**
 * 2013/5/25
 * @author wwj
 * 简单工厂的测试类
 */
public class PizzaTestDriver {
	public static void main(String[] args) {
		SimplePizzaFactory factory = new SimplePizzaFactory();
		PizzaStore store = new PizzaStore(factory);
		
		
		Pizza pizza = store.orderPizza("cheese");
		System.out.println("We ordered a " + pizza.getName() + "\n");
		
		pizza = store.orderPizza("veggie");
		System.out.println("We ordered a " + pizza.getName() + "\n");
	}
}


工厂方法模式实现



项目结构:



/Pizza.java

把Pizza声明为抽象的,让所有具体比萨都必须派生自这个类。
package pizzafm;

import java.util.ArrayList;

/**
 * 2013/5/25
 * @author wwj
 *
 */
public abstract class Pizza {
	String name;	//名称
	String dough;	//面团类型
	String sauce;	//一套佐料
	ArrayList toppings = new ArrayList();
	
	public 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));
		}
	}

	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("Place pizza in official PizzaStore box");
	}

	public String getName() {
		return name;
	}
}


package pizzafm;

/**
 * 纽约披萨
 * @author wwj
 *
 */
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");
	}
	
}


package pizzafm;

public class NYStyleClamPizza extends Pizza {
	public NYStyleClamPizza() {
		name = "NY Style Clam Pizza";
		dough = "Thin Crust Dough";
		sauce = "Marinara Sauce";
 
		toppings.add("Grated Reggiano Cheese");
		toppings.add("Fresh Clams from Long Island Sound");
	}
}


package pizzafm;

public class NYStylePepperoniPizza extends Pizza {
	public NYStylePepperoniPizza() {
		name = "NY Style Pepperoni Pizza";
		dough = "Thin Crust Dough";
		sauce = "Marinara Sauce";
 
		toppings.add("Grated Reggiano Cheese");
		toppings.add("Sliced Pepperoni");
		toppings.add("Garlic");
		toppings.add("Onion");
		toppings.add("Mushrooms");
		toppings.add("Red Pepper");
	}
}


package pizzafm;

public class NYStyleVeggiePizza extends Pizza {
	public NYStyleVeggiePizza() {
		name = "NY Style Veggie Pizza";
		dough = "Thin Crust Dough";
		sauce = "Marinara Sauce";
 
		toppings.add("Grated Reggiano Cheese");
		toppings.add("Garlic");
		toppings.add("Onion");
		toppings.add("Mushrooms");
		toppings.add("Red Pepper");
	}
}


package pizzafm;

/**
 * 芝加哥披萨
 * @author wwj
 *
 */
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");
	}
	public void cut() {
		System.out.println("Cutting the pizza into square slices");
	}
}


package pizzafm;

public class ChicagoStyleClamPizza extends Pizza {
	public ChicagoStyleClamPizza() {
		name = "Chicago Style Clam Pizza";
		dough = "Extra Thick Crust Dough";
		sauce = "Plum Tomato Sauce";
 
		toppings.add("Shredded Mozzarella Cheese");
		toppings.add("Frozen Clams from Chesapeake Bay");
	}
 
	public void cut() {
		System.out.println("Cutting the pizza into square slices");
	}
}


package pizzafm;

public class ChicagoStylePepperoniPizza extends Pizza {
	public ChicagoStylePepperoniPizza() {
		name = "Chicago Style Pepperoni Pizza";
		dough = "Extra Thick Crust Dough";
		sauce = "Plum Tomato Sauce";
 
		toppings.add("Shredded Mozzarella Cheese");
		toppings.add("Black Olives");
		toppings.add("Spinach");
		toppings.add("Eggplant");
		toppings.add("Sliced Pepperoni");
	}
 
	public void cut() {
		System.out.println("Cutting the pizza into square slices");
	}
}


package pizzafm;

public class ChicagoStyleVeggiePizza extends Pizza {
	public ChicagoStyleVeggiePizza() {
		name = "Chicago Deep Dish Veggie Pizza";
		dough = "Extra Thick Crust Dough";
		sauce = "Plum Tomato Sauce";
 
		toppings.add("Shredded Mozzarella Cheese");
		toppings.add("Black Olives");
		toppings.add("Spinach");
		toppings.add("Eggplant");
	}
 
	public void cut() {
		System.out.println("Cutting the pizza into square slices");
	}
}


/PizzaStore.java

此类也是声明为抽象的,实例化比萨的责任由具体的子类来实现
package pizzafm;

/**
 * 2013/5/25
 * @author wwj
 * 让PizzaStore作为超类,让每个域类型都继承这个PizzaStore,每个子类各自决定如何制造披萨
 */
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);
}


package pizzafm;

public class NYPizzaStore extends PizzaStore {

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

}


package pizzafm;

public class ChicagoPizzaStore extends PizzaStore {

	@Override
	Pizza createPizza(String type) {
		if(type.equals("cheese")) {
			return new ChicagoStyleCheesePizza();
		} else if(type.equals("veggie")) {
			return new ChicagoStyleVeggiePizza();
		} else if(type.equals("clam")) {
			return new ChicagoStyleClamPizza();
		} else return null;
	}

}


/PizzaTestDriver.java
package pizzafm;

/**
 * 2013/5/25
 * @author wwj
 * 工厂模式测试驱动类
 */
public class PizzaTestDriver {
	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");
	}
}


抽象工厂模式实现



/Pizza.java

package 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();
	}
}


package pizzaaf;

public class CheesePizza extends Pizza {
	PizzaIngredientFactory ingredientFactory;
	
	public CheesePizza(PizzaIngredientFactory ingredientFactory) {
		this.ingredientFactory = ingredientFactory;
	}

	@Override
	void prepare() {
		System.out.println("Preparing " + name);
		dough = ingredientFactory.createDough();
		sauce = ingredientFactory.createSauce();
		cheese = ingredientFactory.createCheese();
	}

}


package pizzaaf;

public class ClamPizza extends Pizza {
	PizzaIngredientFactory ingredientFactory;
	
	
	public ClamPizza(PizzaIngredientFactory ingredientFactory) {
		this.ingredientFactory = ingredientFactory;
	}

	@Override
	void prepare() {
		System.out.println("PreParing " + name);
		dough = ingredientFactory.createDough();
		sauce = ingredientFactory.createSauce();
		cheese = ingredientFactory.createCheese();
		clam = ingredientFactory.createClam();
	}

}


package pizzaaf;

public class PepperoniPizza extends Pizza {

	PizzaIngredientFactory ingredientFactory;
	 
	public PepperoniPizza(PizzaIngredientFactory ingredientFactory) {
		this.ingredientFactory = ingredientFactory;
	}
 
	void prepare() {
		System.out.println("Preparing " + name);
		dough = ingredientFactory.createDough();
		sauce = ingredientFactory.createSauce();
		cheese = ingredientFactory.createCheese();
		veggies = ingredientFactory.createVeggies();
		pepperoni = ingredientFactory.createPepperoni();
	}
}


package pizzaaf;

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

}


/PizzaIngredientFactory.java

package pizzaaf;

/**
 * 建造原料工厂
 * @author wwj
 * 在接口中,每个原料都有一个对应的方法创造该原料
 */
public interface PizzaIngredientFactory {
	public Dough createDough();
	public Sauce createSauce();
	public Cheese createCheese();
	public Veggies[] createVeggies();
	public Pepperoni createPepperoni();
	public Clams createClam();
}


package pizzaaf;

/**
 * 创建纽约原料工厂
 * @author wwj
 *
 */
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {

	@Override
	public Dough createDough() {
		return new ThinCrustDough();
	}

	@Override
	public Sauce createSauce() {
		return new MarinaraSauce();
	}

	@Override
	public Cheese createCheese() {
		return new ReggianoCheese();
	}

	@Override
	public Veggies[] createVeggies() {
		Veggies veggies[] = {new Garlic(), new Onion(), new MushRoom(), new RedPepper()};
		return veggies;
	}

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

	@Override
	public Pepperoni createPepperoni() {
		return new SlicePepproni();
	}

}


package pizzaaf;

/**
 * 芝加哥披萨原料工厂
 * @author wwj
 *
 */
public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {

	@Override
	public Dough createDough() {
		return new ThickCrustDough();
	}

	@Override
	public Sauce createSauce() {
		return new plumTomatoSauce();
	}

	@Override
	public Cheese createCheese() {
		return new Mozzarella();
	}

	@Override
	public Veggies[] createVeggies() {
		Veggies veggies[] = {new BlackOlives(), new Spinach(), new EggPlant()};
		return veggies;
	}

	@Override
	public Clams createClam() {
		return new FrozenClams();
	}

	@Override
	public Pepperoni createPepperoni() {
		return new SlicedPepperoni();
	}

}


所有原料接口,一系列产品族

package pizzaaf;

public interface Cheese {
	@Override
	public String toString();
}


package pizzaaf;

public interface Clams {
	@Override
	public String toString();
}


package pizzaaf;

public interface Dough {
	@Override
	public String toString();
}


package pizzaaf;

public interface Sauce {
	@Override
	public String toString();
}


package pizzaaf;

public interface Veggies {
	@Override
	public String toString();
}


package pizzaaf;

public interface Pepperoni {
	@Override
	public String toString();
}


实现Cheese的类

package pizzaaf;

public class Mozzarella implements Cheese {
	public String toString() {
		return "Shredded Mozzarella";
	}
}


package pizzaaf;

public class ReggianoCheese implements Cheese {
	public String toString() {
		return "Reggiano Cheese";
	}
}


实现Clams的类

package pizzaaf;

public class FreshClams implements Clams {
	public String toString() {
		return "Fresh Clams from Long Island Sound";
	}
}


package pizzaaf;

public class FrozenClams implements Clams {
	public String toString() {
		return "Frozen Clams from Chesapeake Bay";
	}
}


实现Sauce的类

package pizzaaf;

public class MarinaraSauce implements Sauce {
	public String toString() {
		return "Marinara Sauce";
	}
}


package pizzaaf;

public class plumTomatoSauce implements Sauce {
	public String toString() {
		return "Tomato sauce with plum tomatoes";
	}
}


实现Veggies的类

package pizzaaf;

public class EggPlant implements Veggies {
	public String toString() {
		return "Eggplant";
	}
}


package pizzaaf;

public class Onion implements Veggies {
	public String toString() {
		return "Onion";
	}
}


package pizzaaf;

public class Spinach implements Veggies {
	public String toString() {
		return "Spinach";
	}
}


package pizzaaf;

public class MushRoom implements Veggies {
	public String toString() {
		return "Mushrooms";
	}
}


实现Pepperoni的类

实现Dough的类

package pizzaaf;

public class ThickCrustDough implements Dough {
	public String toString() {
		return "ThickCrust style extra thick crust dough";
	}
}


package pizzaaf;

public class ThinCrustDough implements Dough {
	public String toString() {
		return "Thin Crust Dough";
	}
}


关于工厂模式已经介绍完,蛮多内容的是吧。
什么时候用工厂方法和抽象方法呢?
来听听它们的告白:
抽象工厂:我是抽象工厂,当你需要创建产品家族和想让制造的相关产品集合起来时,你可以使用我。
工厂方法:我是工厂方法,我可以把你的客户代码从实例化的具体类中解耦。或者如果你目前还不知道将来需要实例化哪些具体类时,也可以用我。我的使用方式简单,只要把握继承成子类,并实现我的工厂方法就行了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: