工厂模式详解(简单工厂+工厂方法+抽象工厂)
2017-06-05 00:05
483 查看
这篇文章是对三个工厂模式的分析总结,把三个放在一起希望可以帮到大家更好的理解工厂模式。本文的例子选用的是《head first 设计模式》一书中的披萨店。
问题描述:一个披萨店里有芝士披萨和蔬菜披萨,客人到店里买预定披萨,可能你的代码会这么写:
如果你要添加店里的披萨口味,那你需要添加更多的if else,如果有些口味销量不好,那你有需要去删除多余的if else;这样频繁的修改明显不是我们想要的。这里就要用到简单工厂模式了。
下面先给出uml类图
添加了一个新的工厂类,通过工厂类的createPizza()方法来制作客户需要的披萨具体的代码如下:
SimplePizzaFactory:
写一个披萨的抽象类,所有的披萨继承这个抽象类,我把披萨的切割和包装当做是不变的步骤,不同的披萨准备方法和烘焙方法不一样。
Pizza:
CheesePizza:
VeggiePizza:
PizzaStore:
截图:
到这里算是解决一开始提到的频繁修改问题,接下来披萨店有了新的需求,披萨店要在芝加哥和纽约开分店,但是芝加哥和纽约地区不同口味也会不同。接下来就要通过工厂方法模式来解决问题。
这里修改了PizzaStore类,新增了NYPizzaStore和ChicagoPizzaStore
代码如下:
Pizza:
NYStyleVeggiePizza:
NYStyleCheesePizza:
PizzaStore:
ChicagoPizzaStore:
NYPizzaStore:
截图:
相比之下,简单工厂模式只有一个工厂,工厂方法模式对每一个产品都有相应的工厂。纽约和芝加哥的披萨店分别有不同的工厂,生产不同口味的披萨,满足不同客户的需求。
如果要确保每个披萨店的原料标准化,打算建造一个原料生产的工厂,并将原料运送到各家加盟店。那么就要用到抽象工厂方法了。
UML类图:
代码如下:
Pizza:
CheesePizza:
MaterielFactory:
NYMaterielFactory:
ChicagoMaterielFactory:
PizzaStore:
ChicagoPizzaStore:
NYPizzaStore:
相比之下,工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
问题描述:一个披萨店里有芝士披萨和蔬菜披萨,客人到店里买预定披萨,可能你的代码会这么写:
public void orderPizza(String type){ Pizza pizza = null; if (type.equals("cheese")){ pizza = new CheesePizza(); }else if (type.equals("veggie")){ pizza = new VeggiePizza(); } if (pizza != null){ pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } }
如果你要添加店里的披萨口味,那你需要添加更多的if else,如果有些口味销量不好,那你有需要去删除多余的if else;这样频繁的修改明显不是我们想要的。这里就要用到简单工厂模式了。
简单工厂模式
定义:又叫做静态工厂方法模式,是由一个工厂对象决定创建出哪一种产品类的实例。下面先给出uml类图
添加了一个新的工厂类,通过工厂类的createPizza()方法来制作客户需要的披萨具体的代码如下:
SimplePizzaFactory:
public class SimplePizzaFactory { public static Pizza createPizza(String type){ Pizza pizza = null; if (type.equals("cheese")){ pizza = new CheesePizza(); }else if (type.equals("veggie")){ pizza = new VeggiePizza(); } return pizza; } }
写一个披萨的抽象类,所有的披萨继承这个抽象类,我把披萨的切割和包装当做是不变的步骤,不同的披萨准备方法和烘焙方法不一样。
Pizza:
public abstract class Pizza { public abstract void prepare(); public abstract void bake(); public void cut(){ System.out.println("cut pizza"); }; public void box(){ System.out.println("cut pizza"); }; }
CheesePizza:
public class CheesePizza extends Pizza{ @Override public void prepare() { System.out.println("prepare CheesePizza"); } @Override public void bake() { System.out.println("bake CheesePizza"); } }
VeggiePizza:
public class VeggiePizza extends Pizza{ @Override public void prepare() { System.out.println("prepare VeggiePizza"); } @Override public void bake() { System.out.println("bake VeggiePizza"); } }
PizzaStore:
public class PizzaStore { public void orderPizza(String type){ Pizza pizza; pizza = SimplePizzaFactory.createPizza(type); if (pizza != null){ pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } } public static void main(String[] args) { PizzaStore pizzaStore = new PizzaStore(); pizzaStore.orderPizza("cheese"); pizzaStore.orderPizza("veggie"); } }
截图:
到这里算是解决一开始提到的频繁修改问题,接下来披萨店有了新的需求,披萨店要在芝加哥和纽约开分店,但是芝加哥和纽约地区不同口味也会不同。接下来就要通过工厂方法模式来解决问题。
工厂方法模式
uml类图:这里修改了PizzaStore类,新增了NYPizzaStore和ChicagoPizzaStore
代码如下:
Pizza:
public abstract class Pizza { public abstract void prepare(); public abstract void bake(); public void cut(){ System.out.println("cut pizza"); }; public void box(){ System.out.println("cut pizza"); }; }
NYStyleVeggiePizza:
public class NYStyleVeggiePizza extends Pizza{ @Override public void prepare() { System.out.println("prepare NYStyleVeggiePizza"); } @Override public void bake() { System.out.println("bake NYStyleVeggiePizza"); } }
NYStyleCheesePizza:
public class NYStyleCheesePizza extends Pizza{ @Override public void prepare() { System.out.println("prepare NYStyleCheesePizza"); } @Override public void bake() { System.out.println("bake NYStyleCheesePizza"); } }
PizzaStore:
/** * Created by zhaoyigang on 2017/6/3. */ public abstract class PizzaStore { protected abstract Pizza createPizza(String type); public void orderPizza(String type){ Pizza pizza; pizza = createPizza(type); if (pizza != null){ pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } } public static void main(String[] args) { ChicagoPizzaStore chicagoPizzaStore = new ChicagoPizzaStore(); chicagoPizzaStore.orderPizza("cheese"); NYPizzaStore nyPizzaStore = new NYPizzaStore(); nyPizzaStore.orderPizza("veggie"); } }
ChicagoPizzaStore:
public class ChicagoPizzaStore extends PizzaStore{ @Override protected Pizza createPizza(String type) { if (type.equals("cheese")){ return new ChicagoStyleCheesePizza(); }else if (type.equals("veggie")){ return new ChicagoStyleVeggiePizza(); } return null; } }
NYPizzaStore:
public class NYPizzaStore extends PizzaStore{ @Override protected Pizza createPizza(String type) { if (type.equals("cheese")){ return new NYStyleCheesePizza(); }else if (type.equals("veggie")){ return new NYStyleVeggiePizza(); } return null; } }
截图:
相比之下,简单工厂模式只有一个工厂,工厂方法模式对每一个产品都有相应的工厂。纽约和芝加哥的披萨店分别有不同的工厂,生产不同口味的披萨,满足不同客户的需求。
如果要确保每个披萨店的原料标准化,打算建造一个原料生产的工厂,并将原料运送到各家加盟店。那么就要用到抽象工厂方法了。
抽象工厂方法
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。UML类图:
代码如下:
Pizza:
public abstract class Pizza { private Materiel materiel; public abstract void prepare(); public abstract void bake(); public void cut(){ System.out.println("cut pizza"); } public void box(){ System.out.println("box pizza"); } }
CheesePizza:
public class CheesePizza extends Pizza{ private MaterielFactory materielFactory; public CheesePizza(MaterielFactory materielFactory){ this.materielFactory = materielFactory; } @Override public void prepare() { materielFactory.createMateriel(); System.out.println("prepare cheesePizza"); } @Override public void bake() { System.out.println("bake cheesePizza"); } }
MaterielFactory:
public interface MaterielFactory { public Materiel createMateriel(); }
NYMaterielFactory:
public class NYMaterielFactory implements MaterielFactory{ @Override public Materiel createMateriel() { System.out.println("prepare NYPizzaMateriel"); return new NYPizzaMateriel(); } }
ChicagoMaterielFactory:
public class ChicagoMaterielFactory implements MaterielFactory{ @Override public Materiel createMateriel() { System.out.println("prepare ChicagoPizzaMateriel"); return new ChicagoPizzaMateriel(); } }
PizzaStore:
public abstract class PizzaStore { protected abstract Pizza createPizza(String type); public void orderPizza(String type){ Pizza pizza; pizza = createPizza(type); if (pizza != null){ pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); System.out.println("finished"); System.out.println("***************"); } } public static void main(String[] args) { ChicagoPizzaStore chicagoPizzaStore = new ChicagoPizzaStore(); chicagoPizzaStore.orderPizza("cheese"); NYPizzaStore nyPizzaStore = new NYPizzaStore(); nyPizzaStore.orderPizza("veggie"); } }
ChicagoPizzaStore:
public class ChicagoPizzaStore extends PizzaStore{ @Override protected Pizza createPizza(String type) { ChicagoMaterielFactory chicagoMaterielFactory = new ChicagoMaterielFactory(); if (type.equals("cheese")){ return new CheesePizza(chicagoMaterielFactory); }else if (type.equals("veggie")){ return new VeggiePizza(chicagoMaterielFactory); } return null; } }
NYPizzaStore:
public class NYPizzaStore extends PizzaStore{ @Override protected Pizza createPizza(String type) { NYMaterielFactory materielFactory = new NYMaterielFactory(); if (type.equals("cheese")){ return new CheesePizza(materielFactory); }else if (type.equals("veggie")){ return new VeggiePizza(materielFactory); } return null; } }
相比之下,工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
相关文章推荐
- 工厂模式详解(简单工厂+工厂方法+抽象工厂)
- 创建和使用解耦——工厂模式详解(简单工厂+工厂方法+抽象工厂)
- 设计模式之--工厂模式详解(简单工厂、工厂方法、抽象工厂)
- 工厂模式(简单工厂+工厂方法+抽象工厂)
- Java设计模式---工厂模式(简单工厂、工厂方法、抽象工厂)
- 工厂模式(简单工厂、工厂方法、抽象工厂)
- 小偷公司(文三西路口红灯偷盗)—工厂模式 包括(简单工厂,工厂方法,抽象工厂)(二)
- 详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂)
- 设计模式之三种工厂模式总结(简单工厂、工厂方法、抽象工厂)
- 设计模式-工厂模式(简单工厂、工厂方法、抽象工厂)
- 小偷公司(文三西路口红灯偷盗)—工厂模式 包括(简单工厂,工厂方法,抽象工厂)(三)
- 工厂模式(简单工厂,工厂方法,抽象工厂)
- 工厂模式(简单工厂,工厂方法,抽象工厂)
- 设计模式 - 工厂模式(简单,工厂方法,抽象工厂)
- 设计模式学习003——工厂模式(工厂方法、抽象工厂),简单工厂【也叫静态工厂】
- 设计模式-工厂模式(简单工厂,工厂方法,抽象工厂)
- 工厂模式(简单工厂+工厂方法+抽象工厂)
- 工厂模式总结(简单工厂,工厂方法,抽象工厂)
- 工厂模式(简单工厂+工厂方法+抽象工厂)
- 设计模式解密(2)- 工厂模式(简单工厂、工厂方法、抽象工厂)