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

一. 简单工厂模式

简单工厂模式,它的主要特点是需要在工厂类中做判断,从而创造相应的产品。当增加新的产品时,就需要修改工厂类。举个例子,有一家电子产品生产厂家,它只有一个工厂,能够生产两种型号的产品,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. [Job] 找工作小结

    有近2个月没有更新博客,主要精力放在了投递会议论文和秋招找工作方面.这里简单总结一下秋招笔试面试的几点建议和感受. 投递的NLP算法工程师岗位,主要参加过面试的公司有腾讯(春招),蚂蚁金服(春招),追 ...

  2. win7远程连接全屏和窗口模式切换

    最近开发需要win7远程连接,我知道在连接的时候可以设置全屏模式 但是进去之后想要切换就只能通过快捷键了上网查了一下是ctrl+alt+break.网上说的没有错.我查官方文档也是这样.但是我按的时候 ...

  3. 关于Python json解析过程遇到的TypeError: expected string or buffer

    关于Python json解析过程遇到的问题:(爬取天气json数据所遇到的问题http://tianqi.2345.com/) part.1 url——http://tianqi.2345.com/ ...

  4. java基础之泛型对象与json互转

    1. 场景描述 把泛型对象转成字符串放到缓存中,获取后使用有点问题,记录下,有碰到的朋友,参考下. 2. 解决方案 2.1 操作类及说明 /** * @auther: 软件老王 */ public s ...

  5. App Crawler

    Google官方出了一款App遍历工具App Crawler. 文档:https://developer.android.google.cn/training/testing/crawler App ...

  6. Aria2 1.35.0,更新,测试,发布

    在上一篇: 有哪些便宜还好用的东西,买了就感觉得了宝一样? 结尾提到了Tatsuhiro Tsujikawa的aria2计划在10月更新一个新的版本 今天趁着雨后明月挂天,开始了简单的更新 虽然在半年 ...

  7. 02-20 kd树(鸢尾花分类)

    [TOC] 更新.更全的<机器学习>的更新网站,更有python.go.数据结构与算法.爬虫.人工智能教学等着你:https://www.cnblogs.com/nickchen121/ ...

  8. 02-25 scikit-learn库之决策树

    目录 scikit-learn库之决策树 一.DecisionTreeClassifier 1.1 使用场景 1.2 代码 1.3 参数详解 1.4 属性 1.5 方法 二.DecisionTreeR ...

  9. 关于5G目前形式的浅谈

    目前市面上已经有十几款5G手机已经上市了,但是到2019年底的覆盖率还是非常的低,所以很多换机的用户可以再等一等,2020应该是出来的都是5G手机,也都是支持双模的NA/NSA的两种组网模式,因为工信 ...

  10. spring源码分析系列5:ApplicationContext的初始化与Bean生命周期

    回顾Bean与BeanDefinition的关系. BeanFactory容器. ApplicationContext上下文. 首先总结下: 开发人员定义Bean信息:分为XML形式定义:注解式定义 ...