`
schy_hqh
  • 浏览: 558345 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

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

}
 
 
 
 

 

 

 

  • 大小: 71.2 KB
  • 大小: 59.6 KB
  • 大小: 56.2 KB
  • 大小: 55.6 KB
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    [创建型模式] head first 设计模式之工厂模式(Factory)

    工厂方法(Factory Method)是工厂模式的一种具体实现,它是《Head First 设计模式》这本书中讲解的重点之一。在这个模式中,一个工厂类声明了一个创建对象的抽象方法,但并不实现这个方法。而是由子类决定要实例化...

    Head First 设计模式 (四) 工厂模式(factory pattern) C++实现

    工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,当客户端请求创建一个产品对象时,它只需要一个具体工厂类的引用,而不需要知道如何构造这些对象的细节。这种模式的核心在于封装了...

    Head First设计模式和HeadFirst in java 源码以及23种设计模式关系图

    总的来说,这个压缩包包含的资源可以帮助你深入理解设计模式,通过《HeadFirst设计模式》和《HeadFirst in Java》的源码,你可以学习到如何在实际项目中应用这些模式。而UML类图则提供了直观的视角,便于你把握设计...

    Head First Design Patterns 英文版 Head First设计模式

    《Head First Design Patterns》是一本深入浅出介绍设计模式的图书,由Eric Freeman、Elisabeth Freeman、Bert Bates和Kathy Sierra联合编写。本书结合认知科学原理和神经生物学研究,采用引导式教学方法,通过故事...

    head first 设计模式 高清完整版 pdf

    《Head First设计模式》是一本深受开发者喜爱的经典书籍,它以独特、生动的方式讲解了设计模式这一核心的软件工程概念。设计模式是经验丰富的开发者在解决常见问题时总结出的最佳实践,它们为软件设计提供了可复用的...

    HeadFirst设计模式PPT

    《HeadFirst设计模式》是一本深受开发者欢迎的书籍,它以独特、易理解的方式介绍了软件设计中的重要概念——设计模式。设计模式是经验丰富的开发者在解决常见问题时总结出的最佳实践,它们为软件设计提供了可复用的...

    Head.First设计模式_PDF

    第1章到第11章陆续介绍的设计模式为Strategy、Observer、Decorator、Abstract Factory、Factory Method、Singleton、Command、Adapter、Facade、Template Method、iterator、Composite、State、proxy。最后三章比较...

    headfirst设计模式

    《Head First设计模式》是一本深受开发者欢迎的设计模式教程,以其独特的视觉呈现方式和易于理解的语言,让初学者也能快速掌握设计模式的核心概念。这本书深入浅出地介绍了23种GOF(GoF,Gamma、Erich、Johnson、...

    HeadFirst设计模式源代码

    《HeadFirst设计模式源代码》是一本面向程序员的深度学习设计模式的书籍,它通过直观易懂的方式将复杂的概念转化为生动的图像和有趣的例子,帮助读者深入理解并掌握设计模式。设计模式是软件工程中的一种最佳实践,...

    HeadFirst设计模式英文版

    《Head First 设计模式》的英文版是一本面向初学者的设计模式入门书籍,它以幽默风趣的文风,深入浅出地介绍了软件设计中经常使用的设计模式。设计模式是一套被反复使用、多数人知晓、经过分类编目、代码设计经验的...

    head first 设计模式

    《Head First设计模式》(中文版)共有14章,每章都介绍了几个设计模式,完整地涵盖了四人组版本全部23个设计模式。前言先介绍这本书的用法;第1章到第11章陆续介绍的设计模式为Strategy、Observer、Decorator、...

    head first 设计模式 PDF电子书下载

    《Head First 设计模式》是一本深受欢迎的设计模式书籍,由Eric Freeman、Elisabeth Robson、Bert Bates和Kathy Sierra合著。这本书以其独特的视觉呈现方式和易理解的教学方法,深受程序员们的喜爱,尤其是那些希望...

    HeadFirst设计模式JAVA版源码

    《HeadFirst设计模式JAVA版源码》是一份深入学习设计模式的重要资源,它基于流行的编程语言Java,旨在帮助开发者理解并应用设计模式于实际项目中。设计模式是软件工程中的重要概念,它代表了在特定场景下解决问题的...

    Head First设计模式官方原码

    《Head First设计模式》是一本深受开发者欢迎的设计模式学习书籍,以其独特的教学方式,通过丰富的图解和幽默的语言,帮助读者深入理解设计模式的核心概念。这本书的官方源码提供了书中所讲解的每个设计模式的实际...

    Head First设计模式 源代码

    《Head First设计模式》是软件开发领域的一本经典著作,主要介绍了面向对象设计中的各种模式。这本书通过生动、直观的方式,使读者能够更好地理解和应用设计模式。源代码是书中理论知识的具体实现,可以帮助读者深入...

    Head First 设计模式 JAVA源码

    《HeadFirst设计模式》(中文版)共有14章,每章都介绍了几个设计模式,完整地涵盖了四人组版本全部23个设计模式。前言先介绍这本书的用法;第1章到第11章陆续介绍的设计模式为Strategy、Observer、Decorator、...

    HeadFirst 设计模式java源代码

    《Head First设计模式》(中文版)共有14章,每章都介绍了几个设计模式,完整地涵盖了四人组版本全部23个设计模式。前言先介绍这本书的用法;第1章到第 11章陆续介绍的设计 5b4 式为Strategy、Observer、Decorator、...

    Head First 设计模式(中文版)

    《Head First设计模式》(中文版)共有14章,每章都介绍了几个设计模式,完整地涵盖了四人组版本全部23个设计模式。前言先介绍这本书的用法;第1章到第11章陆续介绍的设计模式为Strategy、Observer、Decorator、...

    Head First设计模式 11个模式案例整合

    《Head First设计模式》是一本深受开发者欢迎的设计模式入门书籍,以其独特的视觉风格和易于理解的方式解释了软件设计中的核心概念。在这个“11个模式案例整合”中,作者通过实例化11个经典设计模式,帮助读者深入...

    HEAD FIRST设计模式

    《Head First设计模式》(中文版)共有14章,每章都介绍了几个设计模式,完整地涵盖了四人组版本全部23个设计模式。前言先介绍这本书的用法;第1章到第11章陆续介绍的设计模式为Strategy、Observer、Decorator、...

Global site tag (gtag.js) - Google Analytics