抽象工厂模式

简介

​ 抽象工厂模式(Abstract Factory Pattern )也是创建型模式之一,为创建一组相关或者是相互依赖的对象提供一个接口,而不需要指定他们的具体类

工厂方法模式和抽象工厂模式的区别

​ 抽象工厂模式与工厂方法模式最大的区别就在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建 。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、有效率。

产品等级结构与产品族

​ 为了便于理解上面的概念,我们需要知道什么是产品等级结构和产品族

产品等级结构

​ 产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。如下图为一个产品等级结构方式:

产品族

​ 在抽象工厂模式中,产品族是位于不同产品等级结构中,功能相关联的产品组成的家族。如下图所示多个产品结构用红箭头标出来的:

  • 每一个产品族中含有产品的数目与产品等级结构的数目是相等的

  • 产品的等级结构与产品族将产品按照不同方向划分,形成一个二维的坐标系,横轴表示产品的等级结构,纵轴表示产品族。

  • 只要指明一个产品所处的产品族以及它所属的等级结构,就可以唯一的确定这个产品。

使用场景

  • 一个系统不应当依赖于产品实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的
  • 这个系统的产品有多于一个的产品族,而系统只消费某一族的产品
  • 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来
  • 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖与实现

"系统只消费某一族的产品" 怎么理解,实际上是与抽象工厂模式的起源有关,具体可以参见《Java与模式》 抽象工厂的起源

UML类图

角色简介

  • factory:抽象工厂角色,它声明了一组用于创建一种产品的方法,每一种方法对应一种产品,如上图的factory就定义了两个方法,分别创建ProductA和ProductB
  • ConcreteFactory:具体工厂角色,它实现了再抽象工厂中定义的创建产品的方法,生成一组具体产品,这些产品构成了一个产品种类,每一个产品都位于某个产品等级结构中,如上图所述的ConcreteFactory1和ConcreteFactory2
  • Product:抽象产品角色,它为每种产品声明接口,比如上述类图中的ProductA和ProductB
  • ConcreteProduct:具体产品角色,它定义具体工厂生产的具体产品,实现抽象产品接口中声明的业务和方法,如上图中ConcreteProductA1、ConcreteProductA2和ConcreteProductB1、ConcreteProductB2

示例

​ 这里我们以奥迪汽车的生产举例,奥迪Q3、Q5、Q7虽然都是一个车系,但是他们三者的零部件差别却很大,就拿Q3和Q7来说,Q3的发动机是国产的,Q7的则是原装进口的,Q3的轮胎是普通的轮胎,而Q7则使用的是全尺寸的越野轮胎;还有Q3使用的是普通的制动系统,Q7则使用制动性能极好的制动系统。Q3和Q7对应的是一些列车,而发动机、轮胎、制动系统则对应的是一系列零部件,两者是两种不同的产品类型,这时候就可以将抽象工厂模式应用到其中,首先汽车工厂需要生产轮胎、发动机、制动系统这3个部分。

首选我们先定义一个抽象车厂类

public interface CarFactory2 {/*** 生产轮胎* @return 轮胎*/ITire createTire();/*** 生产引擎* @return 引擎*/IEngine createEngine();/*** 生产制动系统* @return 制动系统*/IBrake createBrake();
}

其次我们定义零部件抽象类,并实现Q3和Q7所使用的零部件

public interface IBrake {/*** 制动系统*/void brake();
}   
public interface IEngine {/*** 发动机*/void engine();
}
public interface ITire {/*** 轮胎*/void tire();
}

实现Q3的零部件

public class NormalBrake implements IBrake {public void brake() {System.out.println("普通制动");}
}
public class DomesticEngine implements IEngine {public void engine() {System.out.println("国产发动机");}
}
public class NormalTire implements ITire {public void tire() {System.out.println("普通轮胎");}
}

实现Q7的零部件

public class SeniorBrake implements IBrake {public void brake() {System.out.println("高级制动");}
}
public class ImportEngine implements IEngine {public void engine() {System.out.println("进口发动机");}
}
public class SUVTire implements ITire {public void tire() {System.out.println("越野轮胎");}
}

最后我们进行测试

/*** 工厂模式测试类*/
public class FactoryTest {public static void main(String[] args) {// Q3工厂Q3CarFactory2 q3CarFactory2 = new Q3CarFactory2();q3CarFactory2.createBrake().brake();q3CarFactory2.createEngine().engine();q3CarFactory2.createTire().tire();System.out.println("=========================Q3、Q7分隔符================================");// Q7 工厂Q7CarFactory2 q7CarFactory2 = new Q7CarFactory2();q7CarFactory2.createBrake().brake();q3CarFactory2.createEngine().engine();q7CarFactory2.createTire().tire();}
}

打印结果

普通制动
国产发动机
普通轮胎
=========================Q3、Q7分隔符================================
高级制动
国产发动机
越野轮胎

优点

​ 一个显著的优点是分离接口与实现,客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已,使其从具体的产品实现中解耦

​ 同时基于接口与实现的分离,使抽象该工厂方法模式在切换产品类时更加灵活、容易,无需修改已有的系统,符合”开闭-原则“。

缺点

​ 由上面的示例我们可以看出,抽象工厂模式会导致类文件的爆炸性增加,例如上面我们要加入Q5工厂,对应的轮胎,引擎、和制动类又要增加

​ 还有就是不太容易扩展新的产品类,因为每当我们增加一个产品类就需要修改抽象工厂,那么所有的具体工厂类均会被修改。(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)

参考资料

Java与模式 - 书

Android 源码设计模式解析与实战 - 书

转载于:https://www.cnblogs.com/mr-wang1/p/10646381.html

设计模式之 --- 工厂模式(下)相关推荐

  1. Java设计模式(工厂模式>抽象工厂模式和原型模式)

    Java设计模式Ⅱ 1.工厂模式 1.1 简单工厂模式 1.2 工厂方法模式 2.抽象工厂模式 3.总结 4.原型模式 4.1 原型模式 4.2 浅拷贝 4.3 深拷贝 5.建造者模式 1.工厂模式 ...

  2. 设计模式之工厂模式(三)

    上一次我们已经通过代码,简单的认识了工厂方法模式,具体的思路请移步到设计模式之工厂模式(二),进行查看.这次,让我们通过设计模式的思想,来好好认识下工厂方法模式. 创建者和产品 所有工厂模式都用来封装 ...

  3. php工厂模式和单例模式,php 设计模式之工厂模式、单例模式、注册树模式

    php 设计模式之工厂模式.单例模式.注册树模式 在软件工程中,创建型设计模式承担着对象创建的职责,尝试创建适合程序上下文的对象,对象创建设计模式的产生是由于软件工程设计的问题,具体说是向设计中增加复 ...

  4. 系统架构技能之设计模式-抽象工厂模式

    一.上篇回顾 上篇我们主要讲述了简单工厂模式和工厂模式.并且分析了每种模式的应用场景和一些优缺点,我们现在来回顾一下: 简单工厂模式:一个工厂负责所有类型对象的创建,不支持无缝的新增新的类型对象的创建 ...

  5. Java设计模式之工厂模式篇 (转)

    Java设计模式之工厂模式篇 (转)[@more@]Java设计模式之工厂模式篇 作者:冯睿  本文选自:赛迪网 2003年03月07日 .NET.com.cn/servlets/ad?Pool=te ...

  6. Java设计模式之 工厂模式(简单工厂模式)

    前一阵子学习了Java 中据说是最简单的设计模式的 单例模式,想一起讨论学习的小伙伴请点击这里: Java 设计模式之单例模式 那么今天就把学习的工厂模式记录下来 工厂模式: 实现了创建者和调用者的分 ...

  7. Java设计模式之工厂模式 (工厂方法模式)

    上一篇我们学习了简单工厂模式,最后对于增加新产品的缺点,我们在工厂方法模式中解决. 为学习简单工厂模式的小伙伴点击这里Java 设计模式之工厂模式(简单工厂模式) 工厂方法模式要点: 避免简单工厂模式 ...

  8. 设计模式之---工厂模式、建造者模式

    ☺ 对于工厂模式,个人学习需要掌握 注意答案的重点标黑了.对于工厂模式.建造者模式,掌握,我下面这几点就很棒棒. 一.工厂模式 1.什么是工厂模式:[关键字factory] 答:创建对象时,不直接ne ...

  9. 设计模式之工厂模式05

    获取继承该接口的所有类#设计模式之工厂模式05 目标 女娲补天的故事大家都听说过吧,今天不说这个,说女娲创造人的故事,可不是"造人"的工作,这个词被现代人滥用了.这个故事是说,女娲 ...

  10. C#设计模式之工厂模式

    C#设计模式之工厂模式 文章目录 C#设计模式之工厂模式 简单工厂模式 模式分类 模式产生的原因 模式灵感的来源 模式类图 经典代码实现 简单工厂模式的总结(优点和缺点最好在使用中自行体会) 简单工厂 ...

最新文章

  1. linux 命令行简介
  2. 通俗讲解分布式锁,看完不懂算作者输
  3. xml相关php函数,PHP利用xml常用函数的详细集合示例
  4. java generate()_Java IntStream generate()用法及代码示例
  5. python和C语言分别实现插入排序
  6. mysql 3t_编译安装mysql
  7. ubuntu 9 下 LAMP开发环境搭建
  8. InDesign入门教程,如何导入文本?
  9. 6678EMIF总结
  10. WDM驱动开发 电源管理
  11. ubuntu linux 批量删除文件
  12. “1+7+N”改革工作体系介绍
  13. 惠普电脑win10关闭自动调节亮度
  14. 川内计算机专业,川内大学计算机专业排名
  15. 「技术综述」人脸脸型分类研究现状
  16. 本题要求编写程序,将一个给定的整数插到原本有序的整数序列中,使结果序列仍然有序
  17. OBS 基础10 录制视频
  18. 太魔性!甘肃博物馆这匹马“不太正经”
  19. Wireshark, Sniffer and Omnipeek 三款网络分析工具的比较
  20. Metric的快速入门

热门文章

  1. linux的ftp指令发邮件,三种使用Linux命令发送邮件
  2. java播放mp3背景音乐_Java如何实现MP3播放!!
  3. eclipse修改git账号信息
  4. Java lambda list转换map时,把多个参数拼接作为key
  5. Apache Dubbo是一款高性能Java RPC框架。
  6. Linux根据软件包的名称查看可供安装的包
  7. Android Studio升级到2.3的编译问题解决办法
  8. node.js中的文件系统
  9. 数据库设计(五)第一范式(1NF)?
  10. 第三百四十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—爬虫和反爬的对抗过程以及策略—scrapy架构源码分析图...