2018年8月24日17:20:30

抽象工厂模式

定义

借我一只晨光的铅笔,明天就还给你。
现在我可以还你晨光的铅笔了,你早已不在了,明天还是明天。

抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。——《设计模式:可复用面向对象软件的基础》

使用场景

首先要来认识两个新概念:产品族产品等级结构

产品族,是指不同产品等级结构中,功能相关的产品组成的家族。

产品等级结构, 即产品的继承结构,继承(或实现)同一抽象产品的具体产品属于同一产品等级结构。

在后面的代码示例中,晨光文具和真彩文具是两个产品族,继承(或实现)铅笔抽象产品的晨光铅笔和真彩铅笔是一个产品等级结构,继承(或实现)橡皮抽象产品的晨光铅笔和真彩铅笔是另一个产品等级结构。【这个我用了继承(或实现)是因为Java中有接口是实现的,抽象类是继承的,抽象产品既可以是接口,也可以是抽象类,为了不误导我自己,特意加上。】例子还有:Intel的主板、芯片组、CPU是一个产品族,AMD的主板、芯片组、CPU也是一个产品族,而这里有三个产品等级结构,分别是:主板、芯片组、CPU。

想代码示例的时候,想我们经常用的东西,就想到了文具,想到了晨光和真彩。查了一下,没想到小小文具,营业额超十亿。

现在我们的目标是先赚他一个亿,开一家博客园文具(产品族),产品等级结构呢,他们都有,我们直接继承(或实现)他们的抽象产品类就好了,多方便。这就是抽象工厂模式的好处。增加一个产品族,不用破坏原来代码结构,符合开闭原则。

但是只有老产品,没有什么竞争力,要不我们增加一个新产品即新的产品等级结构,暂时就是码农作弊专用智能笔,帮你轻松应对笔试,这时我们就要在博客园文具(产品族)添加新成员,需要在博客园文具具体工厂类中添加相关创建新产品的代码,不符合开闭原则。这就是抽象工厂模式的缺点了。

综上所述,结合其他情况,以下情况可以使用抽象工厂模式:

1、一个系统不应当依赖于产品实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。

2、系统有多于一个的产品,且每次只使用其中一个产品族。

3、属于同一产品族的产品将在一起使用,这一约束应该在系统设计中体现出来。

4、所有产品以自己继承(或实现)的接口出现,从而客户端不依赖于具体实现。

第1点,毋庸置疑。第2点和第3点,说的是我选择晨光文具,我使用的就是晨光的铅笔就要使用晨光的橡皮,要配套使用,不能是我使用了晨光的铅笔却使用真彩的橡皮。这个约束在这个例子看起来有点牵强,但是想一下这样的场景:期末考试要同一文具,有两种选择,一种是晨光,一种是真彩,他们是配套的,晨光的铅笔配晨光的橡皮,真彩的铅笔配真彩的橡皮,这样就舒服了。第4点,面向接口编程,降低耦合。

第2点和第3点,用上面提到的Intel、AMD产品族更贴切,Intel的CPU是无法和AMD的主板匹配的,AMD的CPU也无法和Intel的主板匹配,所以组装电脑的时候,就默认有这个约束:只能使用同一个产品族中的产品。

关于抽象工厂模式的起源,是用于创建分属于不同操作系统的视窗构建。比如:命令按键(Button)与文字框(Text)都是视窗构建,在UNIX操作系统的视窗环境和Windows操作系统的视窗环境中,这两个构建有不同的本地实现,它们的细节有所不同。视窗构建时,只能选择一个操作系统的Button和Text,如果不是,两个操作系统都用不了,我要这视窗有何用?

角色

抽象工厂角色(Abstract Factory):具体工厂(产品族)公共接口

具体工厂角色(Concrete Factory):产品族

抽象产品角色(Abstract Product):产品等级结构

具体产品角色(Concrete Product):产品

图示

代码示例

代码示例类依赖关系图:

抽象工厂角色(AbstractFactory.java)

public interface AbstractFactory {public Pencil createPencil();public Eraser createEraser();
}

具体工厂角色(ChenGuangFactory.java、TrueColorFactory.java)

// 晨光工厂
public class ChenGuangFactory implements AbstractFactory {@Overridepublic Pencil createPencil() {return new ChenGuangPencil();}@Overridepublic Eraser createEraser() {return new ChenGuangEraser();}}
// 真彩工厂
public class TrueColorFactory implements AbstractFactory{@Overridepublic Pencil createPencil() {return new TrueColorPencil();}@Overridepublic Eraser createEraser() {return new TrueColorEraser();}}

抽象产品角色(Pencil.java、Eraser.java)

// 铅笔
public interface Pencil {public void draw();
}
// 橡皮
public interface Eraser {public void erase();
}

具体产品角色(ChenGuangPencil.java、TrueColorPencil.java、ChenGuangEraser.java、TrueColorEraser.java)

// 晨光铅笔
public class ChenGuangPencil implements Pencil {@Overridepublic void draw() {System.out.println("用晨光铅笔画图。");}}
// 真彩铅笔
public class TrueColorPencil implements Pencil {@Overridepublic void draw() {System.out.println("用真彩铅笔画图。");}}// 晨光橡皮
public class ChenGuangEraser implements Eraser {@Overridepublic void erase() {System.out.println("用晨光橡皮擦除晨光铅笔画的图。");}}
// 真彩橡皮
public class TrueColorEraser implements Eraser {@Overridepublic void erase() {System.out.println("用真彩橡皮擦除真彩铅笔画的图。");}}

测试类(AbstractFactoryTest.java)

public class AbstractFactoryTest {public static void main(String[] args) {// 1、晨光AbstractFactory factory = new ChenGuangFactory();Pencil pencil = factory.createPencil();pencil.draw(); // 用晨光铅笔画图。Eraser eraser = factory.createEraser();eraser.erase(); // 用晨光橡皮擦除晨光铅笔画的图。// 2、真彩AbstractFactory factoryT = new TrueColorFactory();Pencil pencilT = factoryT.createPencil();pencilT.draw(); // 用真彩铅笔画图。Eraser eraserT = factoryT.createEraser();eraserT.erase(); // 用真彩橡皮擦除真彩铅笔画的图。}}

测试结果:

优点

1、拥有简单工厂模式、工厂方法模式一样的优点:客户端不需要知道对象被创建的细节

2、当产品族中多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的产品。

3、增加产品族,符合开闭原则。

缺点

1、增加产品等级结构时,不符合开闭原则。

总结

抽象工厂模式在工厂方法模式的基础上,增添了产品族产品等级结构的概念,以及只使用同一个产品族中的约束,使得抽象工厂模式符合现实生活中的某些场景,成为实用的设计模式,再加上抽象工厂模式实现高内聚低耦合,也为其广泛应用提供基础。

(给晨光和真彩做广告,是不是应该收点广告费???)

参考:

《JAVA与模式》之抽象工厂模式

2018年8月25日18:31:58


由于本人水平有限,如果本文有什么错漏,请不吝赐教
感谢阅读,如果您觉得本文对你有帮助的话,可以点个赞同

抽象工厂模式java_抽象工厂模式相关推荐

  1. 抽象工厂模式java_面试官:说一下静态工厂模式,工厂方法模式,抽象工厂的区别吧...

    静态工厂模式 用生活中的场景类比一下这三种模式,假如你想学习Java视频,你得自己到处去找资料,找资料是一个繁琐的过程,过一段时间你又想学Python视频了,你还得去找资料.现在你在学校上学,你想学J ...

  2. 工厂方法模式和抽象工厂模式

    工厂方法模式和抽象工厂模式 工厂方法模式 抽象工厂模式 总结: 工厂方法模式 #include <string> #include <iostream>// Abstract ...

  3. 工厂方法模式与抽象工厂模式的区别

    工厂方法模式: 一个抽象产品类,可以派生出多个具体产品类. 一个抽象工厂类,可以派生出多个具体工厂类. 每个具体工厂类只能创建一个具体产品类的实例. 抽象工厂模式: 多个抽象产品类,每个抽象产品类可以 ...

  4. 设计模式之工厂类模式总结对比、简单工厂模式、工厂方法模式、抽象工厂模式、带反射的工厂模式、例子代码分析、最详细

    1. 题目 假设某公司同时用SqlServer.MySql数据库,即会切换两数据库(不同数据库的sql语句有些许差异),同时,两数据库里均有对Users.Departments表的操作(sql代码不一 ...

  5. 设计模式之工厂模式和抽象工厂模式

    工厂模式(实现创建者和调用者的分离,实现解耦) 本质:实例化对象,用工厂方法代替new()操作: 将选择实现类.创建对象统一管理和控制:从而实现将调用者和实现类解耦: 分类: 简单工厂:用来生产统一等 ...

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

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

  7. 设计模式C#描述之——简单工厂模式、抽象工厂模式、单例与多例模式

    设计模式C#描述之--简单工厂模式 前 言:设计模式是软件开发领域的精髓之一.学好设计模式是目前每一个开发人员的必修课.目前关于设计模式的书很多,其中比较好的有GOF那本的中译本,但并 不很适合初学者 ...

  8. 021 设计模式之工厂方法模式,抽象工厂模式的区别

    简单工厂模式,工厂方法模式和抽象工厂模式的异同 简单工厂模式,工厂方法模式和抽象工厂模式都是属于创建型设计模式,这三种创建型模式都不需要知道具体类.我们掌握一种思想,就是在创建一个对象时,需要把容易发 ...

  9. 简单工厂模式、工厂方法模式、抽象工厂模式 之间的对比

    先看各自的结构: 简单工厂模式(SimpleFactory Mode): 简单工厂模式的思路是,首先我们把一些共性的东西(算法)拿出来,进行抽象,比如加减乘除.然后我们在定义一个类作为工厂类,工厂类的 ...

最新文章

  1. Reddit年度盘点:2019年最佳机器学习项目
  2. 二叉树---根据【先序、中序序列】and【中序、后序序列】,画出二叉树!
  3. hdu 4267 多维树状数组
  4. 柔性体没有应变_灌注式半柔性道面材料抗冲击性能试验研究
  5. python 反射机制
  6. 华为虚拟化Fusionphere中VRM重启
  7. Web应用部署在WebLogic中Basic认证无法运行问题及解决
  8. 如何修改默认字体_Excel技巧:怎么修改默认字体为宋体
  9. php转换emoji表情为图片输出小程序,微信小程序中使用emoji表情相关
  10. 《延禧攻略》的配色,简直美到爆!
  11. python代码如何转java_将简单的Python代码转换为Java方法
  12. SSM整合——简单的小项目实战
  13. SpringSecurity授权
  14. c语言开发 kdj,KDJ——随机指标之王
  15. 读《论证是一门学问》
  16. 李在福羽毛球教学经典视频汇总31集
  17. 银行卡卡号格式规范 每隔4为一个空格
  18. (17) 基于时空网络的出租车OD需求预测
  19. Web安全工具—Sqlmap常用命令和参数(持续更新)
  20. 各种图像处理库中imread函数的区别

热门文章

  1. php处理post表单数据,php – Httpful post表单数据
  2. linux 套接口文件_继上一篇,继续介绍linux 套接口
  3. 如何在eclipse中,为整个工程生成javadoc文档
  4. 部署weblogic 12c时遇到的问题
  5. JavaSE----属性、方法
  6. android 内存溢出检查,Android Handler使用导致内存溢出附带LeakCanary排查
  7. 拉普拉斯变换公式表_复变函数之拉普拉斯变换小结
  8. CentOS7如何关闭防火墙
  9. Postman图片上传用法以及Required request part file is not present的解决方法
  10. eclipse 自定义文档注释的作者