一天一个设计模式---抽象工厂模式
2016-09-08 14:55
281 查看
请参照上篇文章—工厂方法模式
介绍:提供一个创建一系列相关的相互依赖对象的接口,而无需指定它们具体的类。它和工厂方法模式的区别就在于所创建对象的复杂度上。抽象工厂和简单工厂、工厂方法相比是最具一般性的。
场景:接着我们的pizza工厂,不过现在上头又增加了需求。他希望我们在中国pizza下面有番茄酱和沙拉酱两种口味,而美国pizza下面也有有番茄酱和沙拉酱两种口味。如果使用的是工厂方法模式,那么我们就需要再添加4种工厂分布制作不同的产品。
概念:
1. 产品树:中国番茄酱pizza和中国沙拉酱pizza处于同一等级结构(产品树),US番茄酱pizza和US沙拉酱pizza也处于同一等级结构(产品树)
2. 产品族:位于不同产品等级结构中功能相关联的产品组成的家族。中国番茄酱pizza与US番茄酱pizza属于同一产品族,中国沙拉酱pizza与US沙拉酱pizza属于同一产品族
优点:工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。
披萨定义
部分pizza代码,请参照上篇文章—工厂方法模式
抽象工厂
工厂需要能生产中国pizza和美国pizza
番茄酱工厂
能制作所有国家的番茄酱pizza
沙拉酱工厂
能制作所有国家的沙拉酱pizza
提供pizza业务
输出如下:
不足:
如果我们再增加一个产品树(等级结构),比如巴西pizza,那么,我们需要为每个子工厂添加一个巴西披萨的制作方法。
工厂类
提供pizza业务
输出如下:
总结:
工厂模式在具体实践中是使用比较频繁的,但是我们需要了解他们的长处和不足,根据特定情况来决定需要使用的模式。
1. 对于业务不会进行太多变更的,我们可以使用简单工厂
2. 对于只考虑产品树形式的(产品不会再细分子类),可以考虑工厂方法
3. 对于多个产品等级结构的,我们应该选择合适的抽象工厂
更多模式: 一天一个设计模式—分类与六大原则
更多源码: https://github.com/oDevilo/Java-Base
介绍:提供一个创建一系列相关的相互依赖对象的接口,而无需指定它们具体的类。它和工厂方法模式的区别就在于所创建对象的复杂度上。抽象工厂和简单工厂、工厂方法相比是最具一般性的。
场景:接着我们的pizza工厂,不过现在上头又增加了需求。他希望我们在中国pizza下面有番茄酱和沙拉酱两种口味,而美国pizza下面也有有番茄酱和沙拉酱两种口味。如果使用的是工厂方法模式,那么我们就需要再添加4种工厂分布制作不同的产品。
概念:
1. 产品树:中国番茄酱pizza和中国沙拉酱pizza处于同一等级结构(产品树),US番茄酱pizza和US沙拉酱pizza也处于同一等级结构(产品树)
2. 产品族:位于不同产品等级结构中功能相关联的产品组成的家族。中国番茄酱pizza与US番茄酱pizza属于同一产品族,中国沙拉酱pizza与US沙拉酱pizza属于同一产品族
优点:工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。
一、抽象工厂模式
介绍:我们将所有工厂的业务抽象出来,每个工厂必须实现对所有等级类别的产品的生产。每个子工厂用于实现一个产品族的生产。披萨定义
部分pizza代码,请参照上篇文章—工厂方法模式
// 中国番茄酱pizza public class KetchupChinesePizza extends ChinesePizza { @Override public void addSeasoning() { System.out.println("添加番茄酱"); } } // 美国番茄酱pizza public class KetchupUSPizza extends USPizza { @Override public void addSeasoning() { System.out.println("添加番茄酱"); } } // 中国沙拉酱pizza public class SaladChinesePizza extends ChinesePizza { @Override public void addSeasoning() { System.out.println("添加沙拉酱"); } } // 美国沙拉酱pizza public class SaladUSPizza extends USPizza { @Override public void addSeasoning() { System.out.println("添加沙拉酱"); } }
抽象工厂
工厂需要能生产中国pizza和美国pizza
public abstract class PizzaFactory { public abstract ChinesePizza createChinesePizza(); public abstract USPizza createUSPizza(); }
番茄酱工厂
能制作所有国家的番茄酱pizza
public class KetchupPizzaFactory extends PizzaFactory { @Override public ChinesePizza createChinesePizza() { System.out.println("开始制作中国pizza"); KetchupChinesePizza pizza = new KetchupChinesePizza(); pizza.addFlour(); pizza.addWater(); pizza.addSeasoning(); return pizza; } @Override public USPizza createUSPizza() { System.out.println("开始制作美国pizza"); KetchupUSPizza pizza = new KetchupUSPizza(); pizza.addFlour(); pizza.addWater(); pizza.addSeasoning(); return pizza; } }
沙拉酱工厂
能制作所有国家的沙拉酱pizza
public class SaladPizzaFactory extends PizzaFactory { @Override public ChinesePizza createChinesePizza() { System.out.println("开始制作中国pizza"); SaladChinesePizza pizza = new SaladChinesePizza(); pizza.addFlour(); pizza.addWater(); pizza.addSeasoning(); return pizza; } @Override public USPizza createUSPizza() { System.out.println("开始制作美国pizza"); SaladUSPizza pizza = new SaladUSPizza(); pizza.addFlour(); pizza.addWater(); pizza.addSeasoning(); return pizza; } }
提供pizza业务
public class TestMain { public static void main(String[] args) { PizzaFactory kf = new KetchupPizzaFactory(); ChinesePizza pizza1 = kf.createChinesePizza(); PizzaFactory sf = new SaladPizzaFactory(); USPizza pizza2 = sf.createUSPizza(); } }
输出如下:
开始制作中国pizza 加400克面粉 加100ml水 添加番茄酱 开始制作美国pizza 加300克面粉 加100ml水 添加沙拉酱
不足:
如果我们再增加一个产品树(等级结构),比如巴西pizza,那么,我们需要为每个子工厂添加一个巴西披萨的制作方法。
二、静态抽象工厂
场景:为了对上面的不足加以调整,我们可以通过静态工厂结合抽象工厂,并通过反射机制来对pizza进行制作。工厂类
public class SRFactory { public static ChinesePizza createChinesePizza(String name) throws Exception { System.out.println("开始制作中国pizza"); ChinesePizza pizza = (ChinesePizza) Class.forName(name).newInstance(); pizza.addFlour(); pizza.addWater(); pizza.addSeasoning(); return pizza; } public static USPizza createUSPizza(String name) throws Exception { System.out.println("开始制作美国pizza"); USPizza pizza = (USPizza) Class.forName(name).newInstance(); pizza.addFlour(); pizza.addWater(); pizza.addSeasoning(); return pizza; } }
提供pizza业务
public static void main(String[] args) throws Exception { USPizza pizza = SRFactory.createUSPizza("com.devil.designmodel.factory.model.KetchupUSPizza"); ChinesePizza pizza2 = SRFactory.createChinesePizza("com.devil.designmodel.factory.model.SaladChinesePizza"); }
输出如下:
开始制作美国pizza 加300克面粉 加100ml水 添加番茄酱 开始制作中国pizza 加400克面粉 加100ml水 添加沙拉酱
总结:
工厂模式在具体实践中是使用比较频繁的,但是我们需要了解他们的长处和不足,根据特定情况来决定需要使用的模式。
1. 对于业务不会进行太多变更的,我们可以使用简单工厂
2. 对于只考虑产品树形式的(产品不会再细分子类),可以考虑工厂方法
3. 对于多个产品等级结构的,我们应该选择合适的抽象工厂
更多模式: 一天一个设计模式—分类与六大原则
更多源码: https://github.com/oDevilo/Java-Base
相关文章推荐
- 一天一个设计模式之建造者模式(Builder)
- 一天一个设计模式(3):观察者模式
- 一天一个设计模式---工厂方法模式
- 一天一个设计模式---生成器模式
- 一天一个设计模式---适配器模式
- 一天一个设计模式之职责链模式(Chain of Responsibility)
- 一天一个设计模式——开篇概述
- 一天一个设计模式---状态模式
- 一天一个设计模式---装饰者模式
- 一天一个设计模式---分类与六大原则
- 一天一个设计模式(1): 代理模式
- 每天一个设计模式: 抽象工厂模式(AbstractFactory)
- 一天一个设计模式(5):中介者模式
- 一天一个设计模式---享元模式
- 一天一个设计模式之单例模式(singleton)
- 一天一个设计模式(2): 外观模式
- 设计模式: 自己手动写一个工厂模式(整合工厂方法模式和抽象工厂模式)
- 《软件架构与设计模式》关于 抽象工厂模式 的一个小例子
- 一天一个设计模式---模板方法模式
- 一天一个设计模式---观察者模式