Head First Java 设计模式——工厂方法模式
来源:互联网 发布:郑海霞wnba数据 编辑:程序博客网 时间:2024/05/12 14:09
工厂方法模式,定义了了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
抽象工厂模式,提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
书中给出的是一个Pizza店的例子。假设你有一个pizza店,你可能会这样定义你的预定菜单:
Pizza orderPizza() {Pizza pizza = new Pizza();pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;}
你可能需要更多的pizza类型,于是会这样定义
Pizza orderPizza(String type) {Pizza pizza; if(type.equals("cheese")) {pizza = new CheesePizza();} else if(type.equals("greek")) {pizza = new GreekPizza();} else if(type.equals("pepperoni")) {pizza = new PepperoniPizza();}pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;}
但是你以后可能又会增加或减少Pizza的类型,这时你就会发现哪些代码是会变的,哪些是不会变的。
封装创建对象的代码,我们将创建对象移到orderPizza()之外。如下所示:
我们称这个新对象为"工厂",orderPizza()就变成此对象的客户。接下来我们建立一个简单Pizza工厂
public class SimplePizzaFactory {public Pizza createPizza(String type) {Pizza pizza = null;if(type.equals("cheese")) {pizza = new CheesePizza();} else if(type.equals("greek")) {pizza = new GreekPizza();} else if(type.equals("pepperoni")) {pizza = new PepperoniPizza();} else if(type.equals("clam")) {pizza = new ClamPizza();} else if(type.equals("viggie")) {pizza = new ViggiePizza();} return pizza;}}
然后我们重做PizzaStore类
public class PizzaStore {SimplePizzaFactory factory;public PizzaStore(SimplePizzaFactory factory) {this.factory = factory;}Pizza orderPizza(String type) {Pizza pizza; pizza = factory.createPizza(type);pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;}}
接下来我们可能会有不同地方的加盟店,不同的加盟店口味又会有所不同,例如纽约加盟店跟芝加哥加盟店,这个时候你可能会想到为每个地方建议一个工厂分别为NYPizzaFactory、ChicagoFactory。如果你想要预定一个Pizza,你就要像如下调用:
NYPizzaFactory nyFactory = new NYPizzaFactory();PizzaStore nyStore = new PizzaStore(nyFactory);nyStore.orderPizza("Veggie");ChicagoPizzaFactory chicagoFactory = new ChicagoPizzaFactory();PizzaStore chicagoStore = new PizzaStore(chicagoFactory);chicagoStore.orderPizza("Veggie");
但是在推广SimpleFactory时,加盟店采用你的工厂创建Pizza,但是其他部分,却开始采用他们自创的流程:烘烤的做法有些差异、不要切片、使用其他厂商的盒子。这时候,我们可以用工厂方法设计模式来解决问题,如下:
public abstract class PizzaStore {Pizza orderPizza(String type) {Pizza pizza; //把createPizza()方法从工厂对象移回PizzaStore。pizza = createPizza(type);pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;}//把工厂对象移到这个方法中,作为一个抽象方法,允许子类自己实现这个方法,并保证了其他流程不被改变。protected abstract Pizza createPizza(String type);}
开一家纽约加盟店
public class NYPizzaStore extends PizzaStore {Pizza createPizza(String item) {if(type.equals("cheese")) {pizza = new NYStyleCheesePizza();} else if(type.equals("greek")) {pizza = new NYStyleGreekPizza();} else if(type.equals("pepperoni")) {pizza = new NYStylePepperoniPizza();} else if(type.equals("clam")) {pizza = new NYStyleClamPizza();} }}
public abstract class Pizza {String name;String dough;String sauce;ArrayList<String> toppings = new ArrayList<String>();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 class NYStyleCheesePizza extends Pizza {public NYStyleCheesePizza() {name = "NY Style Sauce and Cheese Pizza";doiugh = "Thin Crust Dough";sauce = "Marinara Sauce";toppings.add("Grated Reggiano Cheese");}}
PizzaStore nyPizzaStore = new NYPizzaStore();Pizza pizza = nyPizzaStore.orderPizza("cheese");
所有工厂模式都是用来封装对象的创建。工厂方法模式通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。组成元素有:创造者类(PizzaStore)、产品类(Pizza)。
接下来我们用抽象工厂模式,
首先建造原料工厂。
public interface PizzaIngredientFactory {public Dough createDough(); //创建生面团 public Sauce createSauce(); //创建酱油 public Cheese createCheese(); //创建奶酪public Veggies[] createVeggies(); //创建蔬菜public Pepperoni createPepperoni(); //创建香肠public Clams createClam(); //创建蛤蚌}
创建加盟店的原料工厂
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {public Dough createDough() {return new ThinCrustDough();}public Sauce createSauce() {return new MarinaraSauce();}public Cheese createCheese() {return new ReggianoCheese();}public Veggies[] createVeggies() {Veggies veggies[] {new Garlic(), new Onion(), new Mushroom(), new RedPepper()};return veggies;}public Pepperoni createPepperoni() {return new SlicedPepperoni();}public Clams createClam() {return new FreshClams();}}
重做Pizza
class Pizza {String name;Dough dough;Sauce sauce;Veggies veggies[];Cheese cheese;Pepperoni pepperoni;Clams clam;abstract void prepare() {};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");};void setName(String name) {this.name = name;}}public class CheesePizza extends Pizza {PizzaIngredientFactory ingredientFactory;public CheesePizza(PizzaIngredientFactory factory) {this.ingredientFactory = factory;}void prepare() {System.out.println("Preparing " + name);dough = ingredientFactory.createDough();sauce = ingredientFactory.createSauce();cheese = ingredientFactory.createCheese();}}public class NYPizzaStore extends PizzaStore {protected Pizza createPizza(String item) {Pizza pizza = null;PizzaIngredientFactory ingredientFactory = new PizzaIngredientFactory();if(type.equals("cheese")) {pizza = new CheesePizza(ingredientFactory);pizza.setName("New York Style Cheese Pizza");} else if(type.equals("greek")) {pizza = new GreekPizza(ingredientFactory);pizza.setName("New York Style Greek Pizza");} else if(type.equals("pepperoni")) {pizza = new PepperoniPizza(ingredientFactory);pizza.setName("New York Style Pepperoni Pizza");} else if(type.equals("clam")) {pizza = new ClamPizza(ingredientFactory);pizza.setName("New York Style Clam Pizza");} }}PizzaStore nyPizzaStore = new NYPizzaStore();Pizza pizza = nyPizzaStore.orderPizza("cheese");//这里可能会传入错误的值导致错误,因此我们可以采用枚举类型作为参数。
设计原则:
1、要依赖抽象,不要依赖具体类。
2、倒置原则:变量不可以持有具体类的应用;不要让类派生自具体类;不啊哟覆盖基类中已实现的方法。
- Head First Java 设计模式——工厂方法模式
- Head First 设计模式学习——简单工厂方法-工厂方法模式-抽象工厂模式
- Head First 设计模式 —— 工厂模式与工厂方法
- 工厂模式详解——《参考Head First设计模式》
- <Head First 设计模式>:工厂模式1:方法模式--Pizza
- 《Head First 设计模式》之工厂方法模式
- 《Head first设计模式》学习笔记 - 工厂方法模式
- 《Head first设计模式》学习笔记 – 工厂方法模式
- 《Head first设计模式》学习笔记 – 工厂方法模式
- Head First设计模式笔记(工厂方法模式)
- 《Head First 设计模式》学习笔记——工厂模式 + 抽象工厂模式
- 工厂方法模式——Head First Design Patterns
- Head First设计模式-简单工厂模式
- Head First设计模式-工厂模式
- Head First设计模式-抽象工厂模式
- 《Head First 设计模式》工厂模式
- Head First设计模式-简单工厂模式
- Head First设计模式-抽象工厂模式
- 程序设计-----------活与死、回调以及面向对象设计
- Apple TV app & Asian operators looks to find their own way over-the-top
- ckfinder在IE上不能使用flash上传问题的解决
- js获取当月的最后一天
- 判断 iframe 是否加载完成的完美方法
- Head First Java 设计模式——工厂方法模式
- Erlang学习资源
- 模电与数电的基本知识 (学习备用)
- Qt 程序里播放 flash
- MFC里面的一些用法
- cocos2d中图片和所占用内存的一点总结!
- 查看linux服务器硬盘IO读写负载
- 查看动态链接库中函数参数类型
- Python的列表(list)介绍