创建型设计模式之抽象工厂方法模式
来源:互联网 发布:mac ladybug是什么意思 编辑:程序博客网 时间:2024/05/24 05:04
1 抽象工厂方法模式概念
1.1 介绍
随着客户的要求越来越高,宝马车需要不同配置的空调和发动机等配件。于是这个工厂开始生产空调和发动机,用来组装汽车。这时候工厂有两个系列的产品:空调和发动机。宝马320系列配置A型号空调和A型号发动机,宝马230系列配置B型号空调和B型号发动机。
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。比如宝马320系列使用空调型号A和发动机型号A,而宝马230系列使用空调型号B和发动机型号B,那么使用抽象工厂模式,在为320系列生产相关配件时,就无需制定配件的型号,它会自动根据车型生产对应的配件型号A。
1.2 定义
为创建一组相关或者是相互依赖的对象提供一个接口,而不需要指定他们的具体实现类。
1.3 使用场景
一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。例如:Linix和Windows下都有文本编辑器图片处理器,两者都属于Software软件的范畴,但是他们所在的操作系统不一样,代码的实现逻辑实现也是不同的,也就是具有了共同的约束条件:操作系统类型。于是我们可以使用抽象工厂模式,产生不同操作系统下的编辑器和图片处理器。
2 原型模式UML类图通用
或者
3 通用模式代码
(1)抽象产品类A
public abstract class AbstractProductA { // 每个具体产品子类需要实现的方法 public abstract void method();}
(2)抽象产品类B
public abstract class AbstractProductB { // 每个具体产品子类需要实现的方法 public abstract void method();}
(3)具体产品类A1
public class ConcreteProductA1 extends AbstractProductA { @Override public void method() { System.out.println("具体产品类A1的实现方法"); }}
(4)具体产品类A2
public class ConcreteProductA2 extends AbstractProductA { @Override public void method() { System.out.println("具体产品类A2的实现方法"); }}
(5)具体产品类B1
public class ConcreteProductB1 extends AbstractProductB { @Override public void method() { System.out.println("具体产品类B1的实现方法"); }}
(6)具体产品类B2
public class ConcreteProductB2 extends AbstractProductB { @Override public void method() { System.out.println("具体产品类B2的实现方法"); }}
(7)抽象工厂类
public abstract class AbstractFactory { // 创建A产品家族 public abstract AbstractProductA createProductA(); //创建B产品家族 public abstract AbstractProductB createProductB();}
(8)具体工厂类1
public class ConcreteFactory1 extends AbstractFactory { // 只生产产品等级为1的A产品 public AbstractProductA createProductA() { return new ConcreteProductA1(); } // 只生产产品等级为1的B产品 public AbstractProductB createProductB() { return new ConcreteProductB1(); }}
(9)具体工厂类2
public class ConcreteFactory2 extends AbstractFactory { // 只生产产品等级为2的A产品 public AbstractProductA createProductA() { return new ConcreteProductA2(); } // 只生产产品等级为2的B产品 public AbstractProductB createProductB() { return new ConcreteProductB2(); }}
4 Android源码中的原型模式
抽象工厂模式在Android源码中使用较少,因为很少会出现多个产品种类的情况,大部分使用工厂方法模式即可解决。
(1)MediaPlayer
MediaPlayer Factory分别会生成4个不同的MediaPlayer基类:StagefrightPlayer、NuPlayerDriver、MidiFile和TestPlayerStub,四者均继承于MediaPlayerBase。
5 抽象工厂方法模式实战
虽然Q3、Q5、Q7都是一个车系,但是三者之间的零部件差别却是很大,例如,Q3使用的发动机是国产的,而Q7则是原装进口的;Q3轮胎是普通的轮胎,而Q7则使用的是全尺寸越野轮胎;还有Q3使用的是比较普通的制动系统,而Q7则使用的是制动性能极好的制动系统。Q3、Q7对应的是一系列车,而轮胎、发动机、制动系统则对应的是一系列零部件,两者是两种不同的产品类型,这时候就可以将抽象工厂模式应用到其中。首先汽车工厂需要生产轮胎、发动机、制动系统这3中部件。
(1)轮胎相关类
public interface ITire { /** * 轮胎 */ void tire();}
public class NormalTire implements ITire{ @Override public void tire() { System.out.println("普通轮胎"); }}
public class SUVTire implements ITire{ @Override public void tire() { System.out.println("越野轮胎"); }}
(2)发动机相关类
public interface IEngine { /** *发动机 */ void engine();}
public class DomesticEngine implements IEngine{ @Override public void engine() { System.out.println("国产发动机"); }}
public class ImportEngine implements IEngine{ @Override public void engine() { System.out.println("进口发动机"); }}
(3)制动系统相关类
public interface IBrake { /** *制动系统 */ void brake();}
public class NormalBrake implements IBrake{ @Override public void brake() { System.out.println("普通制动"); }}
public class SeniorBrake implements IBrake{ @Override public void brake() { System.out.println("高级制动"); }}
(4)抽象车厂类
public abstract class CarFactory { /** * 生产轮胎 * * @return 轮胎 * */ public abstract ITire createTire(); /** * 生产发动机 * * @return 发动机 * */ public abstract IEngine createEngine(); /** * 生产制动系统 * * @return 制动系统 * */ public abstract IBrake createBrake();}
(5)Q3工厂类
public class Q3Factory extends CarFactory{ @Override public ITire createTire() { return new NormalTire(); } @Override public IEngine createEngine() { return new DomesticEngine(); } @Override public IBrake createBrake() { return new NormalBrake(); }}
(6)Q7工厂类
public class Q7Factory extends CarFactory{ @Override public ITire createTire() { return new SUVTire(); } @Override public IEngine createEngine() { return new ImportEngine(); } @Override public IBrake createBrake() { return new SeniorBrake(); }}
(7)客户类
public class Client { public static void main(String[] args) { //Q3工厂类 CarFactory factoryQ3 = new Q3Factory(); factoryQ3.createTire().tire(); factoryQ3.createEngine().engine(); factoryQ3.createBrake().brake(); System.out.println("---------------"); //Q7工厂类 CarFactory factoryQ7 = new Q7Factory(); factoryQ7.createTire().tire(); factoryQ7.createEngine().engine(); factoryQ7.createBrake().brake(); }}
(8)结果打印
普通轮胎国产发动机普通制动------------------越野轮胎进口发动机高级制动
可以看出上面模拟了两个工厂,如果有了Q5厂、Q9厂,各自厂家生产的零部件型号种类又不相同,那么我们创建的类文件就会翻倍。这也是抽象工厂模式的一个弊端,所以实际开发中要权衡使用。
6 简单工厂、工厂方法、抽象工厂之区别
简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式。其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性。
6.1 区别
(1)简单工厂
简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。(不修改代码的话,是无法扩展的。)
(2)工厂方法
工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。(在同一等级结构中,支持增加任意产品。)
(3)抽象工厂
抽象工厂是应对产品族概念的。比如说:每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。(应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。)
6.2 举例说明
用种蔬菜的例子来说明事实,最初的时候,由于规模小,只种植一种蔬菜,根菜类蔬菜,这个时候由于种植方式比较简单,采用简单工厂模式即可,主要目的是让工人轻松,下达工厂种植即可。
但是随着种植厂的发展以及市场的需求,要增加一种蔬菜类型种植——茎菜,由于茎菜与根菜种植方式不一致,就需要两个专门的种植工厂来进行管理,那么久采用工厂模式来管理,一个工厂负责一种作物的种植,这个时候产品可以理解为仍然在一个层次。
我用UML图表示三种结构:
(1)简单工厂
(2)工厂方法
(3)抽象工厂
(4)小结
在没一个层次,种菜工人所关心的对象也不一样,在简单工厂模式下,工人要想到种植萝卜还是白菜,在工厂模式下,工人想到是种植根菜还是茎菜,而在抽象工厂模式下,则关心种植基因菜还是非基因菜
7 总结
(1)优点
分离接口与实现,客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已,使其从具体的产品实现中解耦,同时基于接口与实现分离,使抽象该工厂方法模式在切换产品类时更加灵活、容易。
(2)缺点
一是对类文件的爆炸性增加,二是不太容易扩展新的产品类。
8 参考文章与链接
《Android源码设计模式解析与实战》
《设计模式之禅》
《Android源码设计模式解析与实战》读书笔记(六)
设计模式:简单工厂、工厂方法、抽象工厂之小结与区别
抽象工厂模式和工厂方法模式区别
- "围观"设计模式(8)--创建型之简单工厂模式、工厂方法模式、抽象工厂模式
- "围观"设计模式(8)--创建型之简单工厂模式、工厂方法模式、抽象工厂模式
- 创建型设计模式之抽象工厂方法模式
- Java设计模式之创建型模式--工厂方法及抽象工厂模式
- java设计模式之创建型模式-抽象工厂模式
- 创建型设计模式之手工打造、简单工厂、工厂方法和抽象工厂(新)
- 设计模式之抽象工厂方法模式
- 设计模式之抽象工厂方法模式
- 设计模式之《抽象工厂方法模式》
- 设计模式-创建型模式之 Abstract Factory(抽象工厂)
- java设计模式(创建型)之抽象工厂模式
- 创建型设计模式之抽象工厂(Abstract Factory)模式
- 设计模式-创建型之抽象工厂模式
- 创建型:设计模式之抽象工厂模式(二)
- 【设计模式】创建型模式之抽象工厂Abstract Factory
- 设计模式-创建型模式-抽象工厂
- 设计模式-创建型模式-抽象工厂
- 【设计模式】创建型模式-抽象工厂
- 《Python爬虫学习系列教程》学习笔记
- 你问我答-js初学者,有个问题,求大神指教。
- JavaScript实现瀑布流布局
- SQL Server中将多行数据拼接为一行数据(一个字符串)
- 最优矩阵链乘(经典DP)
- 创建型设计模式之抽象工厂方法模式
- 安装caffe的每一个小问题
- 170417 汇编-除法防溢出和数值显示的子程序实操
- dubbo源码分析-RPC远程调用模块与Remoting通讯模块协作细节
- 对象混合
- B. Odd sum
- 关于获得时间的Date用法
- 贪心法——C语言实现最小代价生成树
- CF-Codeforces Round #409 (rated, Div. 2, based on VK Cup 2017 Round 2)-C-Voltage Keepsake