索引

别名

  • Kit

意图

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

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

结构

参与者

AbstractFactory

  • 声明一个创建抽象产品对象的操作接口。

ConcreteFactory

  • 实现创建具体产品对象的操作。

AbstractProduct

  • 为一类产品对象声明一个接口。

ConcreteProduct

  • 定义一个将被相应的具体工厂创建的产品对象。
  • 实现 AbstractProduct 接口。

Client

  • 仅适用由 AbstractFactory 和 AbstractProduct 类声明的接口。

适用性

在以下情况下可以使用 Abstract Factory 模式:

  • 一个系统要独立于它的产品的创建、组合和表示时。
  • 一个系统要由多个产品系列中的一个来配置时。
  • 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
  • 当你提供一个产品类库,而只想显示它们的接口而不是实现时。

缺点

  • 难以支持新种类的产品。支持新种类的产品就需要扩展 AbstractFactory 接口,这将引起所有子类的改变。

效果

  • 它分离了具体的类。
  • 它使得易于交换产品系列。
  • 它有利于产品的一致性。

相关模式

命名约定

使用命名约定是一个好习惯,例如,总是声明那些定义为抽象工厂的类为 XxxKit。

实现

实现方式(一):使用 Factory Method 来实现 Abstract Factory。

一个具体的工厂将为每个产品重定义该工厂方法以指定产品。

  1. namespace AbstractFactoryPattern.Implementation1
  2. {
  3. public abstract class AbstractOrInterfaceOfFactoryKit
  4. {
  5. public abstract AbstractOrInterfaceOfProductA CreateProductA();
  6. public abstract AbstractOrInterfaceOfProductB CreateProductB();
  7. }
  8.  
  9. public abstract class AbstractOrInterfaceOfProductA
  10. {
  11. }
  12.  
  13. public abstract class AbstractOrInterfaceOfProductB
  14. {
  15. }
  16.  
  17. public class ConcreteFactoryKit1 : AbstractOrInterfaceOfFactoryKit
  18. {
  19. public override AbstractOrInterfaceOfProductA CreateProductA()
  20. {
  21. return new ConcreteProductA();
  22. }
  23.  
  24. public override AbstractOrInterfaceOfProductB CreateProductB()
  25. {
  26. return new ConcreteProductB();
  27. }
  28. }
  29.  
  30. public class ConcreteProductA : AbstractOrInterfaceOfProductA
  31. {
  32. }
  33.  
  34. public class ConcreteProductB : AbstractOrInterfaceOfProductB
  35. {
  36. }
  37.  
  38. public class Client
  39. {
  40. public void TestCase1()
  41. {
  42. AbstractOrInterfaceOfFactoryKit kit = new ConcreteFactoryKit1();
  43. AbstractOrInterfaceOfProductA productA = kit.CreateProductA();
  44. AbstractOrInterfaceOfProductB productB = kit.CreateProductB();
  45. }
  46. }
  47. }

实现方式(二):使用 Prototype 来实现 Abstract Factory。

具体工厂使用产品系列中每一个产品的原型实例来初始化,且它通过复制它的原型来创建新的产品。

  1. namespace AbstractFactoryPattern.Implementation2
  2. {
  3. public abstract class AbstractOrInterfaceOfFactoryKit
  4. {
  5. public abstract AbstractOrInterfaceOfProductA CreateProductA();
  6. public abstract AbstractOrInterfaceOfProductB CreateProductB();
  7. }
  8.  
  9. public abstract class AbstractOrInterfaceOfProductA
  10. {
  11. public abstract AbstractOrInterfaceOfProductA Clone();
  12. }
  13.  
  14. public abstract class AbstractOrInterfaceOfProductB
  15. {
  16. public abstract AbstractOrInterfaceOfProductB Clone();
  17. }
  18.  
  19. public class ConcreteFactoryKit1 : AbstractOrInterfaceOfFactoryKit
  20. {
  21. public override AbstractOrInterfaceOfProductA CreateProductA()
  22. {
  23. return new ConcreteProductA();
  24. }
  25.  
  26. public override AbstractOrInterfaceOfProductB CreateProductB()
  27. {
  28. return new ConcreteProductB();
  29. }
  30. }
  31.  
  32. public class ConcreteFactoryKit2 : AbstractOrInterfaceOfFactoryKit
  33. {
  34. private AbstractOrInterfaceOfProductA _prototypeOfProductA;
  35. private AbstractOrInterfaceOfProductB _prototypeOfProductB;
  36.  
  37. public ConcreteFactoryKit2(
  38. AbstractOrInterfaceOfProductA prototypeOfProductA,
  39. AbstractOrInterfaceOfProductB prototypeOfProductB)
  40. {
  41. _prototypeOfProductA = prototypeOfProductA;
  42. _prototypeOfProductB = prototypeOfProductB;
  43. }
  44.  
  45. public override AbstractOrInterfaceOfProductA CreateProductA()
  46. {
  47. return _prototypeOfProductA.Clone();
  48. }
  49.  
  50. public override AbstractOrInterfaceOfProductB CreateProductB()
  51. {
  52. return _prototypeOfProductB.Clone();
  53. }
  54. }
  55.  
  56. public class ConcreteProductA : AbstractOrInterfaceOfProductA
  57. {
  58. public override AbstractOrInterfaceOfProductA Clone()
  59. {
  60. return new ConcreteProductA();
  61. }
  62. }
  63.  
  64. public class ConcreteProductB : AbstractOrInterfaceOfProductB
  65. {
  66. public override AbstractOrInterfaceOfProductB Clone()
  67. {
  68. return new ConcreteProductB();
  69. }
  70. }
  71.  
  72. public class Client
  73. {
  74. public void TestCase2()
  75. {
  76. AbstractOrInterfaceOfFactoryKit kit1 = new ConcreteFactoryKit1();
  77. AbstractOrInterfaceOfProductA productA1 = kit1.CreateProductA();
  78. AbstractOrInterfaceOfProductB productB1 = kit1.CreateProductB();
  79.  
  80. AbstractOrInterfaceOfFactoryKit kit2 = new ConcreteFactoryKit2(productA1, productB1);
  81. AbstractOrInterfaceOfProductA productA2 = kit2.CreateProductA();
  82. AbstractOrInterfaceOfProductB productB2 = kit2.CreateProductB();
  83. }
  84. }
  85. }

实现方式(三):定义可扩展的 Abstract Factory

Abstract Factory 通常为每一种它可以生产的产品定义一个操作。产品的种类被编码在操作型构中。

增加一种新的产品要求改变 Abstract Factory 的接口以及所有与它相关的类。

一个更灵活但不太安全的设计是给创建对象的操作增加一个参数。该参数指定了将被创建的对象的种类。

该参数可以是一个类标识符、一个整数、一个字符串,或其他任何可以标识这种产品的东西。

这样改动之后,Abstract Factory 只需要一个 "Make" 操作和一个指示要创建对象的种类的参数。

  1. namespace AbstractFactoryPattern.Implementation3
  2. {
  3. public enum ProductCategory
  4. {
  5. ProductA,
  6. ProductB,
  7. }
  8.  
  9. public abstract class AbstractOrInterfaceOfFactoryKit
  10. {
  11. public abstract object CreateProduct(ProductCategory category);
  12. }
  13.  
  14. public abstract class AbstractOrInterfaceOfProductA
  15. {
  16. }
  17.  
  18. public abstract class AbstractOrInterfaceOfProductB
  19. {
  20. }
  21.  
  22. public class ConcreteFactoryKit1 : AbstractOrInterfaceOfFactoryKit
  23. {
  24. public override object CreateProduct(ProductCategory category)
  25. {
  26. switch (category)
  27. {
  28. case ProductCategory.ProductA:
  29. return new ConcreteProductA();
  30. case ProductCategory.ProductB:
  31. return new ConcreteProductB();
  32. default:
  33. throw new NotSupportedException();
  34. }
  35. }
  36. }
  37.  
  38. public class ConcreteProductA : AbstractOrInterfaceOfProductA
  39. {
  40. }
  41.  
  42. public class ConcreteProductB : AbstractOrInterfaceOfProductB
  43. {
  44. }
  45.  
  46. public class Client
  47. {
  48. public void TestCase3()
  49. {
  50. AbstractOrInterfaceOfFactoryKit kit = new ConcreteFactoryKit1();
  51. AbstractOrInterfaceOfProductA productA = (AbstractOrInterfaceOfProductA)kit.CreateProduct(ProductCategory.ProductA);
  52. AbstractOrInterfaceOfProductB productB = (AbstractOrInterfaceOfProductB)kit.CreateProduct(ProductCategory.ProductB);
  53. }
  54. }
  55. }

实现方式(四):使用模板以避免创建子类。

使用C#中的泛型实现抽象工厂。

  1. namespace AbstractFactoryPattern.Implementation4
  2. {
  3. public abstract class AbstractOrInterfaceOfFactoryKit
  4. {
  5. public abstract AbstractOrInterfaceOfProductA CreateProductA();
  6. public abstract AbstractOrInterfaceOfProductB CreateProductB();
  7. public abstract AbstractOrInterfaceOfProductC CreateProductC<TC>()
  8. where TC : AbstractOrInterfaceOfProductC, new();
  9. }
  10.  
  11. public abstract class AbstractOrInterfaceOfProductA
  12. {
  13. }
  14.  
  15. public abstract class AbstractOrInterfaceOfProductB
  16. {
  17. }
  18.  
  19. public abstract class AbstractOrInterfaceOfProductC
  20. {
  21. }
  22.  
  23. public class ConcreteFactoryKit1<TA, TB> : AbstractOrInterfaceOfFactoryKit
  24. where TA : AbstractOrInterfaceOfProductA, new()
  25. where TB : AbstractOrInterfaceOfProductB, new()
  26. {
  27. public override AbstractOrInterfaceOfProductA CreateProductA()
  28. {
  29. return new TA();
  30. }
  31.  
  32. public override AbstractOrInterfaceOfProductB CreateProductB()
  33. {
  34. return new TB();
  35. }
  36.  
  37. public override AbstractOrInterfaceOfProductC CreateProductC<TC>()
  38. {
  39. return new TC();
  40. }
  41. }
  42.  
  43. public class ConcreteProductA : AbstractOrInterfaceOfProductA
  44. {
  45. }
  46.  
  47. public class ConcreteProductB : AbstractOrInterfaceOfProductB
  48. {
  49. }
  50.  
  51. public class ConcreteProductC : AbstractOrInterfaceOfProductC
  52. {
  53. }
  54.  
  55. public class Client
  56. {
  57. public void TestCase4()
  58. {
  59. AbstractOrInterfaceOfFactoryKit kit = new ConcreteFactoryKit1<ConcreteProductA, ConcreteProductB>();
  60. AbstractOrInterfaceOfProductA productA = kit.CreateProductA();
  61. AbstractOrInterfaceOfProductB productB = kit.CreateProductB();
  62. AbstractOrInterfaceOfProductC productC = kit.CreateProductC<ConcreteProductC>();
  63. }
  64. }
  65. }

设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

设计模式之美:Abstract Factory(抽象工厂)的更多相关文章

  1. 设计模式02: Abstract Factory 抽象工厂(创建型模式)

    Abstract Factory 抽象工厂(创建型模式) 常见的对象创建方法:    //创建一个Road对象    Road road=new Road();    new的问题:    -实现依赖 ...

  2. 面向对象设计模式纵横谈:Abstract Factory 抽象工厂模式(笔记记录)

         今天是设计模式的第二讲,抽象工厂的设计模式,我们还是延续老办法,一步一步的.演变的来讲,先来看看一个对象创建的问题. 1.如何创建一个对象 常规的对象创建方法: 这样的创建对象没有任何问题, ...

  3. c++ 设计模式9 (Abstract Factory 抽象工厂模式)

    5.2 抽象工厂模式 动机:在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作:同时,由于需求的变化,往往存在更多系列对象的创建工作. 代码示例: 实现利用数据库的业务逻辑,支持多数据库(Sq ...

  4. C#面向对象设计模式纵横谈——3.Abstract Factory 抽象工厂(创建型模式)

    动机(Motivation) 在软件系统中经常面临着“一系列相互依赖的对象”的创建工作,同时,由于需求变化,往往存在更多系列对象的创建工作.如何应对这种变化?如何绕过常规对象的创建,提供一种“封装机制 ...

  5. 设计模式(一): abstract factory抽象工厂模式 -- 创建型模式

    1.定义 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类. 2.适用场景 1.一个系统要独立于它的产品创建.组合和表示. 2.一个系统要由多个产品系列中的一个来配置. 3.当你要 ...

  6. 一天一个设计模式——Abstract Factory抽象工厂模式

    一.模式说明 前面学习了工厂方法(Factory Method)模式.在工厂方法模式中,在工厂方法模式中,父类决定如何生成实例,但并不决定所要生成的具体类,具体的处理交由子类来处理.这里学习的抽象工厂 ...

  7. Java设计模式:Abstract Factory(抽象工厂)模式

    概念定义 抽象工厂(Abstract Factory)模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 抽象工厂模式中,系统的产品有多于一个的产品族(一个产品族里定义多个产品) ...

  8. Abstract Factory 抽象工厂(创建型模式)

    1.常规的对象创建方法(以更换QQ空间主题为例) (这里的常规对象指的是由于业务需求,当前实例化的对象有可能被其他相似的对象(有着共同的特性)所取代,例如更换手机铃声:一首歌取代另一首歌(词,曲,和声 ...

  9. 对象创建型模式------Abstract Factory(抽象工厂)

    1. 意图    提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类.2. 别名    Kit3. 动机        假设我们要开发一款游戏,当然为了吸引更多的人玩,游戏难度不能太大 ...

  10. Abstract factory抽象工厂--对象创建型

    意图: 提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类. 别名:Kit 补充: 抽象产品A : (产品A1 和产品 A2) 抽象产品B : ( 产品B1 和 产品B2) 一般情况 ...

随机推荐

  1. python 格式化 json输出

    利用python格式化json 字符串输出. $ echo '{"json":"obj"}' | python -m json.tool 利用python -m ...

  2. 如何进行服务器的批量管理以及python 的paramiko的模块

    最近对公司的通道机账号进行改造管理,全面的更加深入的理解了公司账号管理的架构.(注:基本上所有的机器上的ssh不能使用,只有部分机器能够使用.为了安全的角度考虑,安装的不是公版的ssh,而都是定制版的 ...

  3. css颜色大全-转载

    FFFFFF #DDDDDD #AAAAAA #888888 #666666 #444444 #000000 #FFB7DD #FF88C2 #FF44AA  #FF0088  #C10066  #A ...

  4. Vc++ 控件用法总结之List Control

    1.新建对话框MFC,在对话框上放一个ListCtrl ID:IDC_PATH View:Report 2.为ListCtrl添加变量 右击->添加变量m_wndPath 3.找到OnInitD ...

  5. mysql 更改自动增长字段值的重新设定

    今天在服务器上MYSQL库里的一个表插入数据,主键id是auto_increment自动增长类型的.发现插入的值从2247734开始,而实际上id的最大值才22722,不明原因. 删除了新增的,opt ...

  6. 当前JS文件中加入其他js文件

    注意:在html文件导入a.js时,应该把script></script写在/body>后面,否则 document.write()方法有问题. 在载入页面后,浏览器输出流自动关闭: ...

  7. 《Linux内核设计与实现》读书笔记 第二章 从内核出发

    一.获取内核源码 1. Git git实际上是一种开源的分布式版本控制工具. Linux作为一个开源的内核,其源代码也可以用git下载和管理 - 获取最新提交到版本树的一个副本 - $ git clo ...

  8. POJ 1228 - Grandpa's Estate 稳定凸包

    稳定凸包问题 要求每条边上至少有三个点,且对凸包上点数为1,2时要特判 巨坑无比,调了很长时间= = //POJ 1228 //稳定凸包问题,等价于每条边上至少有三个点,但对m = 1(点)和m = ...

  9. PTA week10

    // // main.c // Bonus2 // // Created by 余南龙 on 2016/11/27. // Copyright © 2016年 余南龙. All rights rese ...

  10. libev 宏展开

    想看源码,宏太多,看着累,宏展开,再看,功力时间不够,先放下 放上宏展开后的代码. libev4.20 展开方示为 ./configure 修改makefile文件,字符串 替换CC为 CPP 注意要 ...