目录

一、简介

二、与工厂方法区别

三、抽象工厂模式案例

四、总结


一、简介

抽象工厂模式是一种比较常用的模式,其定义如下:

为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

上面的文字说明,并不是很好理解,所以举个简单的例子:

如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机、海尔电冰箱构成了一个产品族。我们将生产海尔电视机、海尔电冰箱(位于不同等级结构中的产品)的工厂就叫做抽象工厂。

二、与工厂方法区别

  • 抽象工厂模式:用来创建一组相关或者相互依赖的对象,针对的多个产品等级结构(如海尔电视机、海尔电冰箱等在不同的产品结构,两者构成一个产品族);
  • 工厂方法模式:针对的是一个产品等级结构(如海尔电视机、松下电视机等都在电视机产品结构);

那么,什么是产品族呢?

所谓产品族,就是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。

三、抽象工厂模式案例

下面,我们还是拿前面工厂方法模式举的例子,讲解一下如何实现抽象工厂模式。抽象工厂模式也就是不仅生产鼠标,同时生产键盘;即抽象工厂类,有生产鼠标,生产键盘两个接口。

相关类图如下:

抽象工厂模式是工厂方法的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。具体实现源码如下:

抽象工厂类:有N个产品族,在抽象工厂类中就应该有N个创建方法。

/*** 抽象工厂类: 生产一个产品族,不仅生产鼠标,还生产键盘**/
public abstract class AbstractPCFactory {/*** 生产鼠标*/public abstract Mouse createMouse();/*** 生产键盘*/public abstract Keyboard createKeyboard();}

抽象产品类Mouse以及具体产品类:

/*** 抽象产品类:鼠标*/
public abstract class Mouse {/*** 点击*/public abstract void click();
}/*** 具体产品类:戴尔鼠标*/
public class DellMouse extends Mouse {@Overridepublic void click() {System.out.println("戴尔鼠标点击...");}
}

抽象产品类Keyboard以及具体产品类:

/*** 抽象产品类:键盘*/
public abstract class Keyboard {/*** 打字*/public abstract void typeWrite();}/*** 具体产品类:戴尔键盘*/
public class DellKeyboard extends Keyboard {@Overridepublic void typeWrite() {System.out.println("戴尔键盘打字...");}}

戴尔工厂:有M个产品等级就应该有M个实现工厂类,在每个实现工厂中,实现不同产品族的生产任务。

/*** 具体工厂类: 戴尔工厂,分别生产戴尔鼠标、戴尔键盘*/
public class DellPCFactory extends AbstractPCFactory {@Overridepublic Mouse createMouse() {return new DellMouse();}@Overridepublic Keyboard createKeyboard() {return new DellKeyboard();}
}

场景类:

/*** 场景类*/
public class Client {public static void main(String[] args) {AbstractPCFactory factory = new DellPCFactory();Keyboard keyboard = factory.createKeyboard();keyboard.typeWrite();Mouse mouse = factory.createMouse();mouse.click();}
}

运行结果:

戴尔键盘打字...
戴尔鼠标点击...

在抽象工厂模式中,假设我们需要增加一个工厂:

假设我们增加惠普工厂,则我们需要增加惠普工厂,和戴尔工厂一样,继承抽象工厂类AbstractPCFactory;然后创建惠普鼠标,继承鼠标类;创建惠普键盘,继承键盘类即可。

相关类图如下:

具体产品类:惠普键盘:

/*** 具体产品类:惠普键盘*/
public class HpKeyboard extends Keyboard {@Overridepublic void typeWrite() {System.out.println("惠普键盘打字...");}}

具体产品类:惠普鼠标:

/*** 具体产品类:惠普鼠标*/
public class HpMouse extends Mouse {@Overridepublic void click() {System.out.println("惠普鼠标点击...");}
}

具体工厂类: 惠普工厂,分别生产惠普鼠标、惠普键盘:

/*** 具体工厂类: 惠普工厂,分别生产惠普鼠标、惠普键盘*/
public class HpPCFactory extends AbstractPCFactory {@Overridepublic Mouse createMouse() {return new HpMouse();}@Overridepublic Keyboard createKeyboard() {return new HpKeyboard();}
}

场景类:

/*** 场景类*/
public class Client {public static void main(String[] args) {AbstractPCFactory factory = new DellPCFactory();Keyboard keyboard = factory.createKeyboard();keyboard.typeWrite();Mouse mouse = factory.createMouse();mouse.click();System.out.println("==========******===========");AbstractPCFactory hpFactory = new HpPCFactory();Keyboard hpKeyboard = hpFactory.createKeyboard();hpKeyboard.typeWrite();Mouse hpMouse = hpFactory.createMouse();hpMouse.click();}
}

在抽象工厂模式中,假设我们需要增加一个产品:

假设我们增加生产耳机EarPhone这个产品,则首先我们需要增加耳机这个抽象产品类,再加上戴尔耳机,惠普耳机这两个具体产品类。之后在抽象工厂类AbstractPCFactory中,增加生产耳机的接口。最后在戴尔工厂,惠普工厂这两个类中,分别实现生产戴尔耳机,惠普耳机的功能。
相关类图如下:

调整之后的相关源码如下:

抽象工厂类:增加生产耳机的方法

/*** 抽象工厂类: 生产一个产品族,不仅生产鼠标,还生产键盘**/
public abstract class AbstractPCFactory {/*** 生产鼠标*/public abstract Mouse createMouse();/*** 生产键盘*/public abstract Keyboard createKeyboard();/*** 生产耳机*/public abstract Earphone createEarPhone();}

EarPhone耳机抽象、具体产品类:

/*** 抽象产品类:耳机*/
public abstract class Earphone {/*** 听音乐*/public abstract void listen();
}/*** 具体产品类:戴尔耳机*/
public class DellEarphone extends Earphone {@Overridepublic void listen() {System.out.println("戴尔耳机听音乐...");}
}/*** 具体产品类:惠普耳机*/
public class HpEarphone extends Earphone {@Overridepublic void listen() {System.out.println("惠普耳机听音乐...");}
}

戴尔具体工厂:增加生产耳机的方法

/*** 具体工厂类: 戴尔工厂,分别生产戴尔鼠标、戴尔键盘*/
public class DellPCFactory extends AbstractPCFactory {@Overridepublic Mouse createMouse() {return new DellMouse();}@Overridepublic Keyboard createKeyboard() {return new DellKeyboard();}@Overridepublic Earphone createEarPhone() {return new DellEarphone();}
}

惠普具体工厂:增加生产耳机的方法

/*** 具体工厂类: 惠普工厂,分别生产惠普鼠标、惠普键盘*/
public class HpPCFactory extends AbstractPCFactory {@Overridepublic Mouse createMouse() {return new HpMouse();}@Overridepublic Keyboard createKeyboard() {return new HpKeyboard();}@Overridepublic Earphone createEarPhone() {return new HpEarphone();}
}

场景类:

/*** 场景类*/
public class Client {public static void main(String[] args) {AbstractPCFactory factory = new DellPCFactory();Keyboard keyboard = factory.createKeyboard();keyboard.typeWrite();Mouse mouse = factory.createMouse();mouse.click();Earphone dellEarPhone = factory.createEarPhone();dellEarPhone.listen();System.out.println("==========******===========");AbstractPCFactory hpFactory = new HpPCFactory();Keyboard hpKeyboard = hpFactory.createKeyboard();hpKeyboard.typeWrite();Mouse hpMouse = hpFactory.createMouse();hpMouse.click();Earphone hpEarPhone = hpFactory.createEarPhone();hpEarPhone.listen();}
}

运行结果:

戴尔键盘打字...
戴尔鼠标点击...
戴尔耳机听音乐...
==========******===========
惠普键盘打字...
惠普鼠标点击...
惠普耳机听音乐...

在场景类中,没有任何一个方法与实现类有关系,对于一个产品来说,我们只要知道它的工厂方法就可以直接产生一个产品对象,无须关心它的实现类。

四、总结

抽象工厂模式的优点:

  • 封装性:每个产品的实现类不是高层模块要关心的,只关心接口,是抽象,它不关心对象时如何创建出来的,工厂类负责这些,只要知道工厂类是谁,就可以创建出一个需要的对象。

抽象工厂模式的缺点:

  • 产品族扩展非常困难,如我们需要新生产一种产品,如上面示例的耳机,这涉及的修改比较多,因为需要同时修改原先的抽象工厂类、已经实现好的具体工厂类以及场景类,这严重违反了开闭原则。

抽象工厂模式的使用场景:

  • 当需要创建的对象是一系列相互关联或相互依赖的产品族时,就可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构,并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。在实际项目中,没太大必要去区分哪些是工厂方法模式以及抽象工厂,只要使用到了工厂模式,并且达到了松耦合的目的,那么这个模式就是合适的。

设计模式 ( 四 ) 抽象工厂模式相关推荐

  1. 设计模式三—抽象工厂模式

    设计模式三-抽象工厂模式 一.定义 抽象工厂模式是工厂方法模式的进一步抽象.如果产品簇中只有一种产品,则退化为工厂方法模式. 二.原理图 三.代码实例 * 苹果和土豆是园丁1的杰作 * 葡萄和西红柿是 ...

  2. C#设计模式(4)——抽象工厂模式

    C#设计模式(4)--抽象工厂模式 一.引言 在上一专题中介绍了工厂方法模式,工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码),而工厂方法 ...

  3. 设计模式系列·抽象工厂模式

    前言 以小说的笔法写的设计模式系列文章,你绝对看得懂![首发于公众号:"聊聊代码"] 设计模式系列·王小二需求历险记(一) 设计模式系列·王小二需求历险记(二) 设计模式系列·封装 ...

  4. 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)

    原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页] [源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Facto ...

  5. 设计模式复习-抽象工厂模式

    设计模式复习-抽象工厂模式 有两种硬件,PC和Phone,有两种系统,Windows和Linux,现在假设PC和Phone上全都能安装这两个系统,并且将来硬件不会在变化,但是系统可能需要扩展,比如扩展 ...

  6. 设计模式之四(抽象工厂模式第三回合)

    原文:设计模式之四(抽象工厂模式第三回合) 前言 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 抽象工厂模式最大的好处便是易于交换产品系列,由于具体工厂类,例如I ...

  7. python抽象工厂模式_Python设计模式之抽象工厂模式

    Python设计模式之抽象工厂模式 这篇文章主要为大家详细介绍了Python设计模式之抽象工厂模式,感兴趣的小伙伴们可以参考一下 python面向对象编程入门,我们需要不断学习进步 "&qu ...

  8. 设计模式-04抽象工厂模式

    设计模式-04抽象工厂模式 文章中涉及到的代码,请自行下载 https://gitee.com/pan_xiao_lei123/designmode.git 前面介绍的工厂方法模式中考虑的是一类产品的 ...

  9. 设计模式——4.抽象工厂模式

    1. 模式动机 在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法.但是有时候我们需要一 ...

  10. Android设计模式之——抽象工厂模式

    一.介绍 抽象工厂模式(Abstract Factory Pattern),也是创建型设计模式之一.前一节我们已经了解了工厂方法模式,那么这个抽象工厂又是怎么一回事呢?大家联想一下现实生活中的工厂肯定 ...

最新文章

  1. 提高SQL语句的性能
  2. Caliburn笔记-Action简写(wpf框架)
  3. XenDesktop 5 SQL Server Mirror事务日志比较大的原因分析
  4. filter 灰度处理:公祭日,一行代码让页面变成黑白色调
  5. EasyUI+JSP之java读取数据库后JSON格式数据的返回及调用
  6. NSString属性什么时候用copy,什么时候用strong?【转】
  7. 微观、宏观、精准 多视角估算数据库性能(选型、做预算不求人)
  8. mysql生成uuid_MySQL生成UUID
  9. 各种计算机绘图的应用场合,cad制图员面试技巧
  10. MySQL数据结构选择的合理性
  11. 用python实现小猪佩奇
  12. window系统中打开命令行的四种方式
  13. ClassName::class
  14. matlab复杂噪声产生实验报告,基于小波信号的噪声消除matlab实验报告.docx
  15. C语言-链表-添加到链表尾部
  16. 用matlab画三叶玫瑰,网上收到的用matlab画玫瑰花的代码怎么不行啊,报告错误,求大神...
  17. 假如开源项目创始人去世了,项目怎么办? - 知乎精华
  18. 蓝桥杯嵌入式史上最全最详细教程教你快速入门
  19. 2020计算机二级考试题库(含答案)
  20. Git - 入门到熟悉_日志管理

热门文章

  1. 贝叶斯概率推断:短信数据推断行为
  2. 极客大学架构师训练营 网络通信协议 非阻塞网络I/O NIO 数据库架构原理 第16课 听课总结
  3. 深度学习基础之sofxmax回归
  4. 609. 在系统中查找重复文件
  5. 《K-means聚类算法研究综述》笔记
  6. DL神经网络权值初始化
  7. hydra怎么构建字典_在Pytorch中构建流数据集
  8. MySQL蜜罐在护网中提取攻击者微信ID
  9. 简单记录 Part1.1
  10. 17.电话号码的字母组合(力扣leetcode) 博主可答疑该问题