HeadFirst(四)Factory 工厂设计模式

当有一堆对象等着被实例化,究竟实现哪个类,需要在运行时由一些条件来决定!

 

如果代码是针对接口编写的,那么通过多态的特性,它就能与任何新的实现类进行绑定,从而实现扩展!

找出会变化的地方,把它们从不变的部分分离出来,单独进行设计!

工厂方法研究:

如何将实例化具体类的代码从应用中抽离,或者封装起来,使它们不会干扰其它部分。

 

每当需求发生变化或者有新的需求时,你必须对原来的代码进行修改才能完成对需求的实现,如果是这样的话,你应该意识到:你的系统在设计上存在严重问题!!!

对修改没关闭,对扩展没开放,3个字--->烂透了!

将创建对象的代码封装到一个对象中,这个对象就叫做工厂!


工厂模式的几种变体(所有的工厂模式都是用来封装对象的创建)

静态工厂

定义外部类Factory,并提供静态方法调用,返回对象

 

简单工厂

定义外部类Factory,使用者需要组合Factory到类中,再委托Factory对象去调用自己的方法返回对象

 

工厂方法

父类定义一个抽象的方法(该方法在框架中被调用),让子类去重写并决定返回对象的类型

工厂方法模式

 定义了一个创建对象的接口(实为一个抽象方法),但由子类决定要实例化的类是哪一个。

工厂方法让类的实例化推迟到子类中进行。

 

抽象工厂

通过接口定义一个抽象的顶层工厂,子类为一系列不同的具体工厂

通过抽象工厂中定义好的接口,创建一个产品家族。

 

 

所有的工厂都是用来封装对象的创建

 

简单工厂,虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体类中解耦

 

工厂方法使用继承,把对象的创建委托给子类,子类实现工厂方法来创建对象

 

抽象工厂使用对象组合,对象的创建被实现在工厂接口所暴露出来的方法中

 

所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合

 

工厂方法允许类将实例化延迟到子类中进行

 

抽象工厂创建相关的对象家族,而不需要依赖它们的具体类

 

依赖倒置原则,指导我们避免依赖具体类型,而要尽量依赖抽象

 

=======================================================================

 

静态工厂(比较常用,因为简单)

好处:不需要创建对象

缺点:不能通过继承来改变方法的行为,几乎不能扩展(已将静态调用写死在代码里)

 

 

package staticfactory;

/**
 * 各种Pizza的基类
 *
 */
public abstract class Pizza {
	
	public void makePizza() {
		this.prepare();
		this.bake();
		this.cut();
		this.box();
	}
	
	abstract void prepare();
	
	abstract void bake();
	
	abstract void cut();
	
	abstract void box();
}
package staticfactory;

public class CheesePizza extends Pizza {

	@Override
	void prepare() {
		System.out.println("prepare CheesePizza");
	}

	@Override
	void bake() {
		System.out.println("bake CheesePizza");
	}

	@Override
	void cut() {
		System.out.println("cut CheesePizza");
	}

	@Override
	void box() {
		System.out.println("box CheesePizza");
	}
	
}
package staticfactory;

public class ClamPizza extends Pizza {

	@Override
	void prepare() {
		System.out.println("prepare ClamPizza");
	}

	@Override
	void bake() {
		System.out.println("bake ClamPizza");
	}

	@Override
	void cut() {
		System.out.println("cut ClamPizza");
	}

	@Override
	void box() {
		System.out.println("box ClamPizza");
	}

}
package staticfactory;

public class VeggiePizza extends Pizza {

	@Override
	void prepare() {
		System.out.println("prepare VeggiePizza");
	}

	@Override
	void bake() {
		System.out.println("bake VeggiePizza");
	}

	@Override
	void cut() {
		System.out.println("cut VeggiePizza");
	}

	@Override
	void box() {
		System.out.println("box VeggiePizza");
	}

}

 

静态工厂(对外提供静态方法进行访问)

package staticfactory;

public class StaticPizzaFactory {
	
	/**
	 * 负责创建各种类型Pizza的工厂,且为static的!
	 */
	public static Pizza createPizza(String pizzaName) {

		Pizza pizza = null;

		if(pizzaName==null || "".equals(pizzaName.trim())) {
			throw new RuntimeException("Please specify your pizza!");
		}
		try {
			Class<?> clazz = Class.forName(pizzaName);
			pizza = (Pizza) clazz.newInstance(); 
		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
			
		return pizza;
	}
}

Pizza店

package staticfactory;

public class PizzaStore {
	
	public Pizza orderPizza(String cheeseName) {
		Pizza pizza;
		pizza = StaticPizzaFactory.createPizza(cheeseName);
		pizza.makePizza();
		return pizza;
	}

}

测试

package test;

import staticfactory.PizzaStore;

public class PizzaTest {
	public static void main(String[] args) {
		PizzaStore store = new PizzaStore();
		orderPizza(store);
	}

	private static void orderPizza(PizzaStore store) {
		store.orderPizza("staticfactory.CheesePizza");
		store.orderPizza("staticfactory.ClamPizza");
		store.orderPizza("staticfactory.VeggiePizza");
	}
}

 

=======================================================================

简单工厂

组合工厂到类中

package simplefactory;

public class PizzaStore {
	//与工厂组合
	SimplePizzaFactory factory;
	
	public PizzaStore(SimplePizzaFactory simplePizzaFactory) {
		factory = simplePizzaFactory;//实例化工厂
	}
	
	public Pizza orderPizza(String cheeseName) {
		Pizza pizza;
		pizza = factory.createPizza(cheeseName);//委托工厂创建Pizza
		pizza.makePizza();
		return pizza;
	}

}

简单工厂(非静态),需要由对象来调用工厂中的方法

package simplefactory;

public class SimplePizzaFactory {
	
	/**
	 * 负责创建各种类型Pizza的工厂
	 */
	public Pizza createPizza(String pizzaName) {

		Pizza pizza = null;

		if(pizzaName==null || "".equals(pizzaName.trim())) {
			throw new RuntimeException("Please specify your pizza!");
		}
		try {
			Class<?> clazz = Class.forName(pizzaName);
			pizza = (Pizza) clazz.newInstance(); 
		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
			
		return pizza;
	}
}

测试

package test;

import simplefactory.SimplePizzaFactory;
import simplefactory.PizzaStore;

public class PizzaTest {
	public static void main(String[] args) {
		//创建工厂实例对象
		SimplePizzaFactory factory = new SimplePizzaFactory();
		//将工厂对象传入PizzaStore的构造方法中
		PizzaStore store = new PizzaStore(factory);
		orderPizza(store);
	}

	private static void orderPizza(PizzaStore store) {
		store.orderPizza("simplefactory.CheesePizza");
		store.orderPizza("simplefactory.ClamPizza");
		store.orderPizza("simplefactory.VeggiePizza");
	}
}

=======================================================================

工厂方法

 

基类不知道运行时会是哪一个子类在运行---> 解耦, 基类只知道子类可以具备某些行为

具体的对象都是在运行时通过多态实现动态绑定的!

编程时只面对接口,而不是实现类,让代码更具弹性,应对未来的扩展!



 

简单工厂与工厂方法的区别:

简单工厂,是一个被PizzaStore使用的对象,简单工厂作为外部一个类被组合到PizzaStore中;

简单工厂,把全部的事情在一个地方都处理完了。

 

工厂方法,有一个抽象方法createPizza(),由PizzaStore的子类自行负责createPizza()的行为;

工厂方法,创建了一个框架(框架依赖工厂方法创建具体类),让子类决定要如何实现。

设计原则

依赖抽象,不要依赖具体类

不能让高层组件依赖于底层组件,而且,不管高层或底层组件,两者都应该依赖于抽象

简单点说,就是要面向抽象编程

 

变量不可以持有具体类的引用

如果使用new,就会持有具体类的引用。

你可以改用工厂来避开这样的做法。

不要让类派生自具体类

如果派生自具体类,你就依赖具体类。

请派生自一个抽象(接口或抽象类)。

不要覆盖基类中已经实现的方法

如果覆盖基类已经实现的方法,那么你的基类就不是一个真正适合被继承的抽象。

基类中已实现的方法,应该由所有子类共享。

 

尽量达到上述要求,而不是随时都要遵守,根据实际情况考量!

Pizza 抽象类

package factorymethode;

import java.util.ArrayList;

public abstract class Pizza {
	
	String name;//名称
	String dough;//面团
	String sauce;//果酱
	
	ArrayList<String> toppings = new ArrayList<String>();//若干佐料
	
	public void prepare(){
		System.out.println("firsrt: Prepare " + name);
		System.out.println("second: Tossing dough...");
		System.out.println("third: Add sauce...");
		System.out.println("fouth: Add toppings: ");
		for(String topping : toppings) {
			System.out.print("    " + topping);
		}
		System.out.println();
	}
	
	public void bake() {
		System.out.println("Bake for 25 minutes");
	}
	
	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;
	}
}
 

具体的Pizza-NYStyleCheesePizza

package factorymethode;

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");
	}
	
}
 

具体的Pizza---ChicagoStyleCheesePizza

package factorymethode;

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");
	}

	/**
	 * 覆盖父类的方法
	 */
	@Override
	public void cut() {
		System.out.println("Cutting the pizza into square slices");
	}
	
	
	
}
 

PizzaStore抽象类

package factorymethod.pizza;

import factorymethode.Pizza;

public abstract class PizzaStore {
	/**
	 * 订购Pizza的流程是久经考验的,用final修饰,不允许子类进行改变!
	 * 
	 * 提供了一般的框架(定义好流程),以便创建Pizza
	 * 依赖抽象工厂方法创建具体的子类,并创建出实际的Pizza
	 */
	final public Pizza orderPizza(String type) {
		//依赖与抽象
		Pizza pizza;//超类型/父类/接口
		
		//调用抽象工厂方法,在运行时由具体的子类来返回实例对象
		pizza = createPizza(type);
		
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		
		return pizza;
		
	}
	
	/**
	 * 工厂移到这里了,不再单独定义,而是用一个方法(抽象工厂方法)完成对象的创建
	 * 具体对象由子类根据各自的需求进行返回---解耦
	 * 
	 * 参数化工厂方法,参数错误将发生运行时异常
	 * 解决办法:使用枚举类型作为参数,在编译期对参数进行检查
	 * @return 具体的子类对象
	 */
	abstract Pizza createPizza(String type);
}
 

具体的PizzaStore---NYPizzaStore

package factorymethod.pizza;

import factorymethode.NYStyleCheesePizza;
import factorymethode.Pizza;

public class NYPizzaStore extends PizzaStore {
	
	/**
	 * 子类对抽象方法进行实现
	 * 返回自己需要的对象
	 */
	@Override
	Pizza createPizza(String type) {
		if(type.equals("cheese")) {
			return new NYStyleCheesePizza();
		}
		return null;
	}

}
  具体的PizzaStore---ChicagoPizzaStore
package factorymethod.pizza;

import factorymethode.ChicagoStyleCheesePizza;
import factorymethode.Pizza;

public class ChicagoPizzaStore extends PizzaStore {

	/**
	 * 子类对抽象方法进行实现
	 * 返回自己需要的对象
	 */
	@Override
	Pizza createPizza(String type) {
		if(type.equals("cheese")) {
			return new ChicagoStyleCheesePizza();
		}
		return null;
	}

}
  测试
package test;

import factorymethod.pizza.ChicagoPizzaStore;
import factorymethod.pizza.NYPizzaStore;
import factorymethod.pizza.PizzaStore;
import factorymethode.ChicagoStyleCheesePizza;


public class PizzaTest {
	public static void main(String[] args) {
		
		orderNYStylePizza();
		
		System.out.println("==========================");
		
		orderChicagoStylePizza();
		
	}

	private static void orderChicagoStylePizza() {
		PizzaStore store = new ChicagoPizzaStore();
		store.orderPizza("cheese");
	}

	private static void orderNYStylePizza() {
		PizzaStore store = new NYPizzaStore();
		store.orderPizza("cheese");
	}

}
 

=======================================================================

抽象工厂

 提供一个接口(抽象方法),用于创建相关或依赖对象的家族(A1产品,A2产品...)

 抽象工厂用来完成一组产品对象的创建

 

抽象工厂实际内部使用了工厂方法模式

factory1:创建A产品A1,B产品B1

factory2:创建A产品A2,B产品B2

...

上面每一个factory,都是一个工厂方法模式的应用

这些不同的factory,又有自己的基类工厂,abstractFactory

在Client中,只面向abstractFactory,通过abstractFactory进行调用即可。

如此组合起来,就形成了抽象工厂模式

Client(PizzaStore超类)中提供一个抽象方法,这个抽象方法在子类中实现时,将调用上面的abstractFactory进行产品A,B 的创建

 

基类中组合抽象的基类

在运行时通过多态特性,实现不同子类对象的动态绑定!

 



 



 

 

工厂方法与抽象工厂的比较

工厂方法:

通过继承父类,实现父类的抽象方法并返回具体的对象

如,NYPizzaStore继承PizzaStore,通过实现createPizza()返回NYStyleCheesePizza

 

抽象工厂:

通过对象间的组合,通过被组合的对象去调用子类的方法,完成所需对象的创建

如,NYStyleCheesePizza中,通过与PizzaIngredientFactory进行组合,在覆盖父类的抽象方法prepare()时,调用PizzaIngredientFactory对一组原料对象进行创建

 

可以把一组相关的产品集中起来进行创建;

缺点:如果需要扩展新的产品,就必须改变接口;

 

抽象工厂模式应用示例

不同地区的PizzaStore需要使用不同的原料来制作Pizza

原料---接口

public interface Cheese {

}
public interface Clam {

}
public interface Dough {

}
public interface Pepperoni {

}
public interface Sauce {

}
public interface Veggies {

}

具体原料---纽约PizzaStore使用的原料,芝加哥PizzaStore使用的原料

public class ChicagoCheese implements Cheese{

}
 
public class NYCheese implements Cheese{

}
 
public class ChicagoClam implements Clam{

}
 
public class NYClam implements Clam{

}
 
public class ChicagoDough implements Dough{

}
 
public class NYDough implements Dough{

}
 ....其它原料类似,不再列出   抽象工厂---定义一组方法对Pizza原料进行创建
package abstractfactory;

import abstractfactory.ingredient.Cheese;
import abstractfactory.ingredient.Clam;
import abstractfactory.ingredient.Dough;
import abstractfactory.ingredient.Pepperoni;
import abstractfactory.ingredient.Sauce;
import abstractfactory.ingredient.Veggies;

/**
 * 定义一组产品的创建 
 */
public interface PizzaIngredientFactory {
	public abstract Dough createDough();
	public abstract Sauce createSauce();
	public abstract Cheese createCheese();
	public abstract Veggies[] createVeggies();
	public abstract Pepperoni createPepperoni();
	public abstract Clam createClam();
}
  具体工厂---NYPizzaIngredientFactory
package abstractfactory;

import abstractfactory.ingredient.Cheese;
import abstractfactory.ingredient.Clam;
import abstractfactory.ingredient.Dough;
import abstractfactory.ingredient.Pepperoni;
import abstractfactory.ingredient.Sauce;
import abstractfactory.ingredient.Veggies;
import abstractfactory.ingredient.impl.NYCheese;
import abstractfactory.ingredient.impl.NYClam;
import abstractfactory.ingredient.impl.NYDough;
import abstractfactory.ingredient.impl.NYPepperoni;
import abstractfactory.ingredient.impl.NYSauce;
import abstractfactory.ingredient.impl.VeggieGarlic;
import abstractfactory.ingredient.impl.VeggieOnion;

/**
 * 纽约原料工厂
 *
 */
public class NYPizzaIngredientFactory implements PizzaIngredientFactory{

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

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

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

	@Override
	public Veggies[] createVeggies() {
		Veggies[] veggies = {new VeggieGarlic(), new VeggieOnion()};
		return veggies;
	}

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

	@Override
	public Clam createClam() {
		return new NYClam();
	}

}
  具体工厂---ChicagoPizzaIngredientFactory
package abstractfactory;

import abstractfactory.ingredient.Cheese;
import abstractfactory.ingredient.Clam;
import abstractfactory.ingredient.Dough;
import abstractfactory.ingredient.Pepperoni;
import abstractfactory.ingredient.Sauce;
import abstractfactory.ingredient.Veggies;
import abstractfactory.ingredient.impl.ChicagoCheese;
import abstractfactory.ingredient.impl.ChicagoClam;
import abstractfactory.ingredient.impl.ChicagoDough;
import abstractfactory.ingredient.impl.ChicagoPepperoni;
import abstractfactory.ingredient.impl.ChicagoSauce;
import abstractfactory.ingredient.impl.VeggieGarlic;
import abstractfactory.ingredient.impl.VeggieOnion;

/**
 * 芝加哥原料工厂 
 *
 */
public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory{

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

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

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

	@Override
	public Veggies[] createVeggies() {
		Veggies[] veggies = {new VeggieGarlic(), new VeggieOnion()};
		return veggies;
	}

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

	@Override
	public Clam createClam() {
		return new ChicagoClam();
	}

}
  Pizza类
package abstractfactory.pizza;

import java.util.ArrayList;

import abstractfactory.ingredient.Cheese;
import abstractfactory.ingredient.Clam;
import abstractfactory.ingredient.Dough;
import abstractfactory.ingredient.Pepperoni;
import abstractfactory.ingredient.Sauce;
import abstractfactory.ingredient.Veggies;

public abstract class Pizza {
	
	String name;//名称
	
	/**
	 * Pizza制作中需要用到的各种原料
	 */
	Dough dough;//面团
	Sauce sauce;//果酱
	Veggies veggies;//蔬菜
	Cheese cheese;//奶酪
	Pepperoni pepperoni;//香肠切片
	Clam clam;//蚌
	
	ArrayList<String> toppings = new ArrayList<String>();//若干佐料
	
	/**
	 * 需要被子类实现的接口(设计模式中,接口的意思:一个抽象方法,一个interface,或一个抽象类)
	 * 子类在实现时,将利用自己的工厂来创建自己的产品(Dough,Sauce,Veggies,Cheese等的具体类)
	 */
	public abstract void prepare();
	
	public void bake() {
		System.out.println("Bake for 25 minutes");
	}
	
	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 void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
}
  具体的Pizza---NYStyleCheesePizza
package abstractfactory.pizza;

import abstractfactory.PizzaIngredientFactory;

/**
 * 通过抽象工厂完成对一组原料的实例化
 *
 */
public class NYStyleCheesePizza extends Pizza {
	//与原料工厂进行组合
	PizzaIngredientFactory ingredientFactory;//---抽象工厂模式
	
	public NYStyleCheesePizza(PizzaIngredientFactory ingredientFactory) {
		this.ingredientFactory = ingredientFactory;
	}
	
	/**
	 * 运行时将由传入的具体原料工厂完成对应原料的创建
	 */
	@Override
	public void prepare() {
		System.out.println("Preparing "+name);
		//通过原料工厂,对从父类继承下来的那些属性进行初始化
		dough = ingredientFactory.createDough();
		sauce = ingredientFactory.createSauce();
		cheese = ingredientFactory.createCheese();
	}
	
}
  具体的Pizza---ChicagoStyleCheesePizza
package abstractfactory.pizza;

import abstractfactory.PizzaIngredientFactory;

/**
 * 通过抽象工厂完成对一组原料的实例化
 *
 */
public class ChicagoStyleCheesePizza extends Pizza {
	//与原料工厂进行组合
	PizzaIngredientFactory ingredientFactory;//---抽象工厂模式
	
	public ChicagoStyleCheesePizza(PizzaIngredientFactory ingredientFactory) {
		this.ingredientFactory = ingredientFactory;
	}

	/**
	 * 覆盖父类的方法
	 */
	@Override
	public void cut() {
		System.out.println("Cutting the pizza into square slices");
	}
	
	/**
	 * 运行时将由传入的具体原料工厂完成对应原料的创建
	 */
	@Override
	public void prepare() {
		System.out.println("Preparing "+name);
		//通过原料工厂,对从父类继承下来的那些属性进行初始化
		dough = ingredientFactory.createDough();
		sauce = ingredientFactory.createSauce();
		cheese = ingredientFactory.createCheese();
		clam = ingredientFactory.createClam();
	}
	
	
	
}
  PizzaStore
package abstractfactory.store;

import abstractfactory.pizza.Pizza;


public abstract class PizzaStore {
	/**
	 * 订购Pizza的流程是久经考验的,用final修饰,不允许子类进行改变!
	 * 
	 * 提供了一般的框架(定义好流程),以便创建Pizza
	 * 依赖抽象工厂方法创建具体的子类,并创建出实际的Pizza
	 */
	final public Pizza orderPizza(String type) {
		//依赖与抽象
		Pizza pizza;//超类型/父类/接口
		
		//调用抽象工厂方法,在运行时由具体的子类来返回实例对象
		pizza = createPizza(type);
		
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		
		return pizza;
		
	}
	
	/**
	 * 工厂移到这里了,不再单独定义,而是用一个方法(抽象工厂方法)完成对象的创建
	 * 具体对象由子类根据各自的需求进行返回---解耦
	 * 
	 * 参数化工厂方法,参数错误将发生运行时异常
	 * 解决办法:使用枚举类型作为参数,在编译期对参数进行检查
	 * @return 具体的子类对象
	 */
	abstract Pizza createPizza(String type);//---工厂方法模式
}
  具体的PizzaStore----NYPizzaStore
package abstractfactory.store;

import abstractfactory.NYPizzaIngredientFactory;
import abstractfactory.PizzaIngredientFactory;
import abstractfactory.pizza.NYStyleCheesePizza;
import abstractfactory.pizza.Pizza;

public class NYPizzaStore extends PizzaStore {
	
	/**
	 * 子类对抽象方法进行实现---工厂方法模式
	 * 返回自己需要的对象
	 */
	@Override
	Pizza createPizza(String type) {
		
		Pizza pizza = null;
		
		//引入New York的原料工厂
		//工厂在方法中被指定,外部并不需要知道
		PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
		
		if(type.equals("cheese")) {
			pizza = new NYStyleCheesePizza(ingredientFactory);
			pizza.setName("New York Style Cheese Pizza from abstract factory!");
			return pizza;
		}
		
		return null;
	}

}
  具体的PizzaStore----ChicagoPizzaStore
package abstractfactory.store;

import abstractfactory.ChicagoPizzaIngredientFactory;
import abstractfactory.PizzaIngredientFactory;
import abstractfactory.pizza.ChicagoStyleCheesePizza;
import abstractfactory.pizza.Pizza;


public class ChicagoPizzaStore extends PizzaStore {

	/**
	 * 子类对抽象方法进行实现---工厂方法模式
	 * 返回自己需要的对象
	 */
	@Override
	Pizza createPizza(String type) {
		Pizza pizza = null;
		
		//引入Chicago的原料工厂
		//工厂在方法中被指定,外部并不需要知道
		PizzaIngredientFactory ingredientFactory = new ChicagoPizzaIngredientFactory();
		
		
		if(type.equals("cheese")) {
			pizza = new ChicagoStyleCheesePizza(ingredientFactory);
			pizza.setName("Chicago Style Cheese Pizza from abstract factory!");
			return pizza;
		}
		return null;
	}

}
  测试
package test;

import abstractfactory.store.ChicagoPizzaStore;
import abstractfactory.store.NYPizzaStore;
import abstractfactory.store.PizzaStore;



public class PizzaTest {
	public static void main(String[] args) {
		
		orderNYStylePizza();
		
		System.out.println("==========================");
		
		orderChicagoStylePizza();
		
	}

	private static void orderChicagoStylePizza() {
		PizzaStore store = new ChicagoPizzaStore();
		store.orderPizza("cheese");
	}

	private static void orderNYStylePizza() {
		PizzaStore store = new NYPizzaStore();
		store.orderPizza("cheese");
	}

}
       

猜你喜欢

转载自schy-hqh.iteye.com/blog/1988941