工厂模式属于创建型模式,大致可以分为三类,简单工厂模式、工厂方法模式、抽象工厂模式。

一. 简单工厂模式

简单工厂模式,它的主要特点是需要在工厂类中做判断,从而创造相应的产品。当增加新的产品时,就需要修改工厂类。举个例子,有一家电子产品生产厂家,它只有一个工厂,能够生产两种型号的产品,A 和 B。可以想像一下,A是电吹风,B是电风扇。客户需要什么样的吹风类产品,一定要显示地告诉生产工厂。

代码实现:

  1. enum CTYPE {PRODUCT_A, PRODUCT_B};
  2. //抽象产品类
  3. class Product
  4. {
  5. public:
  6. virtual void Show() = 0;
  7. };
  8. //具体产品A
  9. class ProductA: public Product
  10. {
  11. public:
  12. void Show() { cout<<"Product A"<<endl; }
  13. };
  14. //具体产品B
  15. class ProductB: public Product
  16. {
  17. public:
  18. void Show() { cout<<"Product B"<<endl; }
  19. };
  20. //唯一的工厂,可以生产两种型号的产品,在内部判断
  21. class Factory
  22. {
  23. public:
  24. Product* CreateProduct(enum CTYPE ctype)
  25. {
  26. if(ctype == PRODUCT_A) //工厂内部判断
  27. return new ProductA(); //生产产品A
  28. else if(ctype == PRODUCT_A)
  29. return new ProductB(); //生产产品B
  30. else
  31. return NULL;
  32. }
  33. };
  34. int main()
  35. {
  36. Factory fac; //工厂
  37. Product *pro = fac.CreateProduct(PRODUCT_A);//生产产品A
  38. pro->Show();
  39. return 0;
  40. }

缺点:

由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。

打个比方:

这个工厂在刚建厂时,就要事先把以后的要生产的产品考虑好,部门划分好。如果要生产新的产品,就要改变工厂的空间布局,部门也要重新划分,这是很不利的。当然如果工厂以后发展不大,也就是创建的对象比较少时,还是可以用的。

二. 工厂方法模式

所谓工厂方法模式,是指定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。

还以刚才的例子解释,这家电子厂赚了不少钱,于是决定再开设一个厂,其中一个工厂专门用来生产A型号的产品,也就是只生产电吹风,而另一工厂专门用
来生产B型号的产品,也就是只生产电风扇,这样分工明确了。以后客户要再下定单时,可以直接找到相关的工厂了,比如要A型号的产品,就找A工厂要,不再担
心下的定单是A,生产出来的是B产品了。

代码实现:

  1. class Product
  2. {
  3. public:
  4. virtual void Show() = 0;
  5. };
  6. //产品A
  7. class ProductA: public Product
  8. {
  9. public:
  10. void Show()
  11. {
  12. cout<<"Product A"<<endl;
  13. }
  14. };
  15. //产品B
  16. class ProductB: public Product
  17. {
  18. public:
  19. void Show()
  20. {
  21. cout<<"Product B"<<endl;
  22. }
  23. };
  24. //抽象工厂
  25. class Factory
  26. {
  27. public:
  28. virtual Product* CreateProduct() = 0;
  29. };
  30. //生产A的工厂
  31. class FactoryA: public Factory
  32. {
  33. public:
  34. Product* CreateProduct()
  35. {
  36. return new ProductA;
  37. }
  38. };
  39. //生产B的工厂
  40. class FactoryB: public Factory
  41. {
  42. public:
  43. Product* CreateProduct()
  44. {
  45. return new ProductB;
  46. }
  47. };
  48. int main()
  49. {
  50. Factory* fac = new FactoryA(); //A工厂
  51. Product* p = fac->CreateProduct(); //生产产品
  52. p->Show();
  53. return 0;
  54. }

其实你会发现,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行,你想要加功能,本来是改工厂类的,而现在是修改客户端。

这有什么好处呢?举个例子,有三个客户原来要A产品,现在改卖B产品,在代码中体现为:

简单工厂的处理:

  1. Factory fac; //工厂
  2. Product *pro1 = fac.CreateProduct(PRODUCT_A);//生产产品A
  3. Product *pro2 = fac.CreateProduct(PRODUCT_A);//生产产品A
  4. Product *pro3 = fac.CreateProduct(PRODUCT_A);//生产产品A
  5. //改为B产品,这里要改三个地方
  6. //Product *pro1 = fac.CreateProduct(PRODUCT_B);//生产产品B
  7. //Product *pro2 = fac.CreateProduct(PRODUCT_B);//生产产品B
  8. //Product *pro3 = fac.CreateProduct(PRODUCT_B);//生产产品B
  9. pro1->Show();
  10. pro2->Show();
  11. pro3->Show();

工厂方法的处理:

  1. Factory* fac = new FactoryA(); //A工厂
  2. //改为B产品,这里只改一个地方
  3. //Factory* fac = new FactoryB(); //B工厂
  4. Product* pro1 = factory_A->CreateProduct(); //生产产品
  5. Product* pro2 = factory_A->CreateProduct(); //生产产品
  6. Product* pro3 = factory_A->CreateProduct(); //生产产品
  7. pro1->Show();
  8. pro2->Show();
  9. pro3->Show();

这里可以看到工厂方法的好处了吧,工厂方法模式是简单工厂模式的进一步抽象和推广,它集中封装了对象的创建,使得要更换产品时,不需要做大的改动就可以实现,降低了客户程序与产品对象的耦合。

优点:

相对于简单工厂模式来说,这样分工更加明确,当需要新产品时,就建一个新的工厂,而不是对原工厂类进行修改。这样做满足了"开放-封闭"原则,即可以扩展,不可修改。

缺点:

1. 每增加一种产品,就需要增加一个对象的工厂。在C++实现中,就是要定义一个个的工厂类。显然,相比简单工厂模式,工厂方法模式需要更多的类定义。

2. Factory 模式仅仅局限于一类类(就是说 Product 是一类,有一个共同的基类),如果我们要为不同类的类提供一个对象创建的接口,那就要用AbstractFactory了。

打个比方:

如果这家公司发展迅速,推出了很多新的产品,那么就要开设相应的新工厂,一种产品一个工厂。这对于客户来说是好事,分工明确了白;但对于工厂自己来说开销也变大了。

如要我想要生产核心芯片,但是芯片不是产品,不能继承于product类。因为产品和零部件,不是一类。

三. 抽象工厂模式

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

还以上面的例子解释,这家公司经营的还不错,针对其核心技术都申请了专利,后来生始生产相关电子芯片了
(像三星一样,即生产产品也生产芯片)。对于这种情况,我们不能在抽象产品类上继承一个零部件,因为产品和芯片没有什么共同之处,完全是两个领域。你要做
芯片,就要专心做,当成一个新的领域,不能用以前产品的那一套流程。这样划分才明确,才能更好的实现高内聚,低耦合的明标。

  1. //抽象产品类
  2. class Product
  3. {
  4. public:
  5. virtual void Show() = 0;
  6. };
  7. //产品A
  8. class ProductA: public Product
  9. {
  10. public:
  11. void Show()
  12. {
  13. cout<<"Product A"<<endl;
  14. }
  15. };
  16. //产品B
  17. class ProductB: public Product
  18. {
  19. public:
  20. void Show()
  21. {
  22. cout<<"Product B"<<endl;
  23. }
  24. };
  25. //抽象芯片类
  26. class Chip
  27. {
  28. public:
  29. virtual void Show() = 0;
  30. };
  31. //芯片A
  32. class ChipA: public Chip
  33. {
  34. public:
  35. void Show()
  36. {
  37. cout<<"Chip A"<<endl;
  38. }
  39. };
  40. //芯片B
  41. class ChipB: public Chip
  42. {
  43. public:
  44. void Show()
  45. {
  46. cout<<"Chip B"<<endl;
  47. }
  48. };
  49. //抽象工厂类
  50. class Factory
  51. {
  52. public:
  53. virtual Product* CreateProduct() = 0;
  54. virtual Chip* CreateChip() = 0;
  55. };
  56. //生产A的工厂
  57. class FactoryA: public Factory
  58. {
  59. public:
  60. Product* CreateProduct() //产品
  61. {
  62. return new ProductA;
  63. }
  64. Chip* CreateChip() //芯片
  65. {
  66. return new ChipA;
  67. }
  68. };
  69. //生产B的工厂
  70. class FactoryB: public Factory
  71. {
  72. public:
  73. Product* CreateProduct() //产品
  74. {
  75. return new ProductB;
  76. }
  77. Chip* CreateChip()  //芯片
  78. {
  79. return new ChipB;
  80. }
  81. };
  82. int main()
  83. {
  84. Factory* factury = new FactoryA(); //A工厂
  85. Product* product = factury->CreateProduct(); //生产产品
  86. Chip* chip = factury->CreateChip(); //生产芯片
  87. product->Show();
  88. chip->Show();
  89. return 0;
  90. }

我们可以发现,抽象工厂比工厂模式所能处理的产品更多,最关健的是这些产品有不同的基类。

优点:

1. AbstractFactory 模式关键就是将这一组对象的创建封装到一个用于创建对象的工厂类(ConcreteFactory)中,维护这样一个工厂创建类总比维护 n 多相关对象的创建过程要简单的多。

2. 它的最大好处是易于交换产品系列,比如我要B工厂的产品,只需要在客户端代码修改一处即可。

打个比方:

这时客户只要知道A工厂是生产A类的产品和芯片的,B工厂是生产B类的,其它都不用关心,只要想要与A类相关的东东就去找A就行了。

四. 总结:

1. 简单工厂模式,所有的产品都在工厂类中进行生产。功能单一时,没有什么问题,但是当增加很多新产品时,就要不断的修改产品类,易于出错,也违反了对修改是封闭的原则。

2. 工厂方法模式,每个工厂生产一种产品,这样分工更加明确。当增加新产品时,只需增加一个工厂类,而不用修改原有工厂类,这样工厂类的耦合度就降低了。

3. 抽象工厂模式,比工厂方法模式处理的情况更多。主要是对不同产品的处理,这时的工厂能够生产多种产品,这多种产品虽然没有共同基类,但是却属于一类,具体体现在都是由同一个工厂生产。

设计模式C++描述----03.工厂(Factory)模式的更多相关文章

  1. Java设计模式(二) 工厂方法模式

    本文介绍了工厂方法模式的概念,优缺点,实现方式,UML类图,并介绍了工厂方法(未)遵循的OOP原则 原创文章.同步自作者个人博客 http://www.jasongj.com/design_patte ...

  2. 设计模式-03工厂方法模式(Factory Method Pattern)

    插曲.简单工厂模式(Simple Factory Pattern) 介绍工厂方法模式之前,先来做一个铺垫,了解一下简单工厂模式,它不属于 GoF 的 23 种经典设计模式,它的缺点是增加新产品时会违背 ...

  3. 设计模式(2)工厂方法模式(Factory Method)

    设计模式(0)简单工厂模式 设计模式(1)单例模式(Singleton) 源码地址 0 工厂方法模式简介 0.0 工厂方法模式定义 工厂方法模式是在简单工厂模式基础上,为解决更复杂的对象创建问题而衍生 ...

  4. 设计模式(三)工厂方法模式(Factory Pattern)

    一.引言 在简单工厂模式中讲到简单工厂模式的缺点,有一点是——简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过于复杂,然而本专题介绍的工厂方法模式可以 ...

  5. [设计模式3]--工厂(Factory)模式

    原文出处:http://blog.csdn.net/lwbeyond/article/details/7528309 工厂模式属于创建型模式,大致可以分为三类,简单工厂模式.工厂方法模式.抽象工厂模式 ...

  6. Head First 设计模式 —— 04. 工厂 (Factory) 模式

    思考题 如何将实例化具体类的代码从应用中抽离,或者封装起来,使它们不会干扰应用的其他部分? P111 将实例化具体类的代码放入一个对象中管理,通过不同入参决定实例化具体的类 简单工厂 不是23种GOF ...

  7. PHP设计模式(二)工厂方法模式(Factory Method For PHP)

    简单工厂简述: 简单工厂模式实现了生产产品类的代码跟客户端代码分离,在工厂类中你可以添加需要生成长跑的逻辑代码(new 产品类),但是问题来了,优秀的代码是符合"开闭原则"如果你要 ...

  8. JAVA设计模式——第 5 章 工厂方法模式【Factory Method Pattern】(转)

    女娲补天的故事大家都听说过吧,今天不说这个,说女娲创造人的故事,可不是“造人”的工作,这个词被现代人滥用了.这个故事是说,女娲在补了天后,下到凡间一看,哇塞,风景太优美了,天空是湛蓝的,水是清澈的,空 ...

  9. Java设计模式学习笔记(三) 工厂方法模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...

随机推荐

  1. awk 命令使用

    awk命令就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理.例如: awk -F '/' '{print $NF}' tmp/file.txt 该命令用于读取file. ...

  2. CSS div仿table样式

    要想让div元素显示的样式与table相同,那么需要使用display属性,这个属性将告诉浏览器这些数据是制表的,将以哪种样式来渲染数据: // table --使该元素按table样式渲染 // t ...

  3. Vagrant定制个性化CentOS7虚拟机模板

    关于虚拟机模板 想用vagrant搭建hadoop集群,要完成以下准备工作: 三个虚拟机实例操作系统都是CentOS7的server版: 每个实例都要安装同样的应用.关闭防火墙.关闭swap等: 今天 ...

  4. Kubernetes 系列(六):Kubernetes部署Prometheus监控

    1.创建命名空间 新建一个yaml文件命名为monitor-namespace.yaml,写入如下内容: apiVersion: v1 kind: Namespace metadata: name: ...

  5. HDU 2044——一只小蜜蜂...(DP)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2044 题解 //递归思想,超时 #include<iostream> using namesp ...

  6. 自己动手实现智能家居之温湿度数据采集存储(DHT11,MySql)

    [前言] 一个热爱技术的人一定向往有一个科技感十足的环境吧,那何不亲自实践一下属于技术人的座右铭:"技术改变世界". 就让我们一步步动手搭建一个属于自己的"智能家居平台& ...

  7. (转) websocket 和 socket 剖析

    Socket 与 WebSocket 本站文章除注明转载外,均为本站原创或者翻译. 本站文章欢迎各种形式的转载,但请18岁以上的转载者注明文章出处,尊重我的劳动,也尊重你的智商: 本站部分原创和翻译文 ...

  8. [Swoole] 在Ubuntu下安装、快速开始

    本文主要讲述在 Ubuntu 下编译安装 Swoole,并根据官方文档给出的demo进行了测试和搬运,包括:TCP服务器.UDP服务器.HTTP服务器.WebSocket服务器.异步客户端.定时器和协 ...

  9. python语言程序设计基础(嵩天)第二章课后习题

    p56: *2.1 实例1的修改.改造实例代码1.1,采用eval(input(<提示内容>))替换现有输入部分,并使输出的温度值为整数. 源代码: TempStr=input(" ...

  10. selenium+testNG自动化测试框架搭建

    自动化测试框架搭建 1 Java环境的搭建 1.1访问oracle的官网下载最新版本的jdk http://www.oracle.com/technetwork/java/javase/downloa ...