1. 概念

  • 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
  • 在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

2. 介绍

意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
主要解决:主要解决接口选择的问题。
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决:在一个产品族里面,定义多个产品。
关键代码:在一个工厂里聚合多个同类产品。
应用实例:工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、时尚男装,这些也都是成套的,即一系列具体产品。假设一种情况(现实中是不存在的,要不然,没法进入共产主义了,但有利于说明抽象工厂模式),在您的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 OOP 的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。
注意事项:产品族难扩展,产品等级易扩展。

3. 代码实现

Phone和WiFI类

  1. //手机接口
  2. public interface CellPhoneProduter {
  3. void start();
  4. void clos();
  5. void call();
  6. void send();
  7. }
  8. //路由器
  9. public interface RouterProducter {
  10. void start();
  11. void clos();
  12. void openWiFi();
  13. void setting();
  14. }

具体的phone和具体的wifi

  1. //华为手机
  2. public class HuaWeiPhoneProduter implements CellPhoneProduter {
  3. @Override
  4. public void start() {
  5. System.out.println("华为开机");
  6. }
  7. @Override
  8. public void clos() {
  9. System.out.println("华为关机");
  10. }
  11. @Override
  12. public void call() {
  13. System.out.println("用华为打电话");
  14. }
  15. @Override
  16. public void send() {
  17. System.out.println("用华为发短信");
  18. }
  19. }
  20. public class HuaWeiRouterProducter implements RouterProducter {
  21. @Override
  22. public void start() {
  23. System.out.println("华为路由器启动");
  24. }
  25. @Override
  26. public void clos() {
  27. System.out.println("华为路由器关闭");
  28. }
  29. @Override
  30. public void openWiFi() {
  31. System.out.println("华为打开wifi");
  32. }
  33. @Override
  34. public void setting() {
  35. System.out.println("华为设置wifi");
  36. }
  37. }
  38. //小米手机
  39. public class XiaoMiPhoneProduter implements CellPhoneProduter {
  40. @Override
  41. public void start() {
  42. System.out.println("开启小米手机");
  43. }
  44. @Override
  45. public void clos() {
  46. System.out.println("关闭小米手机");
  47. }
  48. @Override
  49. public void call() {
  50. System.out.println("用小米手机打电话");
  51. }
  52. @Override
  53. public void send() {
  54. System.out.println("用小米手机发短信");
  55. }
  56. }
  57. public class XiaoMiRouterProducter implements RouterProducter {
  58. @Override
  59. public void start() {
  60. System.out.println("小米路由器启动");
  61. }
  62. @Override
  63. public void clos() {
  64. System.out.println("小米路由器关闭");
  65. }
  66. @Override
  67. public void openWiFi() {
  68. System.out.println("小米打开wifi");
  69. }
  70. @Override
  71. public void setting() {
  72. System.out.println("小米设置wifi");
  73. }
  74. }

抽象工厂

  1. //抽象工厂
  2. public interface ProducterFactory {
  3. //生产手机
  4. CellPhoneProduter cellPhoneProduter();
  5. //生产路由器
  6. RouterProducter routerProducter();
  7. }

具体工厂

  1. //华为工厂
  2. public class HuaWeiFactory implements ProducterFactory{
  3. @Override
  4. public CellPhoneProduter cellPhoneProduter() {
  5. //生产华为手机
  6. return new HuaWeiPhoneProduter();
  7. }
  8. @Override
  9. public RouterProducter routerProducter() {
  10. //生产华为路由器
  11. return new HuaWeiRouterProducter();
  12. }
  13. }
  14. //小米工厂
  15. public class XiaoMiFactory implements ProducterFactory{
  16. @Override
  17. public CellPhoneProduter cellPhoneProduter() {
  18. //生产小米手机
  19. return new XiaoMiPhoneProduter();
  20. }
  21. @Override
  22. public RouterProducter routerProducter() {
  23. //生产小米路由器
  24. return new XiaoMiRouterProducter();
  25. }
  26. }

消费者测试

  1. //客户端
  2. public class Client {
  3. public static void main(String[] args) {
  4. System.out.println("=================小米系列产品===============");
  5. //小米工厂
  6. XiaoMiFactory xiaoMiFactory = new XiaoMiFactory();
  7. //小米手机
  8. CellPhoneProduter XiaoMiPhone = xiaoMiFactory.cellPhoneProduter();
  9. XiaoMiPhone.call();
  10. XiaoMiPhone.clos();
  11. XiaoMiPhone.send();
  12. XiaoMiPhone.start();
  13. //小米路由器
  14. RouterProducter XiaoMiRouter = xiaoMiFactory.routerProducter();
  15. XiaoMiRouter.openWiFi();
  16. XiaoMiRouter.clos();
  17. XiaoMiRouter.setting();
  18. XiaoMiRouter.start();
  19. System.out.println("=================华为系列产品===============");
  20. //华为工厂
  21. HuaWeiFactory huaWeiFactory = new HuaWeiFactory();
  22. //华为手机
  23. CellPhoneProduter HuaWeiPhone = huaWeiFactory.cellPhoneProduter();
  24. HuaWeiPhone.call();
  25. HuaWeiPhone.clos();
  26. HuaWeiPhone.send();
  27. HuaWeiPhone.start();
  28. //华为路由器
  29. RouterProducter HuaWeiRouter = xiaoMiFactory.routerProducter();
  30. HuaWeiRouter.openWiFi();
  31. HuaWeiRouter.clos();
  32. HuaWeiRouter.setting();
  33. HuaWeiRouter.start();
  34. }
  35. }

4. 流程(未更新)

image.png

5. 解释

https://www.jianshu.com/p/5fb1e21c4d19

(1) 产品等级结构:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
(2) 产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机、海尔电冰箱构成了一个产品族。

产品族与产品等级结构示意图

不同颜色的多个正方形、圆形和椭圆形分别构成了三个不同的产品等级结构,而相同颜色的正方形、圆形和椭圆形构成了一个产品族,每一个形状对象都位于某个产品族,并属于某个产品等级结构。图3中一共有五个产品族,分属于三个不同的产品等级结构。我们只要指明一个产品所处的产品族以及它所属的等级结构,就可以唯一确定这个产品。
当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构、属于不同类型的具体产品时就可以使用抽象工厂模式。抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形式。抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、更有效率。
image.png
每一个具体工厂可以生产属于一个产品族的所有产品,例如生产颜色相同的正方形、圆形和椭圆形,所生产的产品又位于不同的产品等级结构中。如果使用工厂方法模式,上图所示结构需要提供15个具体工厂,而使用抽象工厂模式只需要提供5个具体工厂,极大减少了系统中类的个数。

6. 总结

所以这也就不难理解为什么qq换皮肤一套一套换,因为这一套皮肤就是一个产品族。一次换一套皮肤就是一次换一个产品族。操作系统的所有东西比如window的和linux的就是两个不同的产品族。