经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
深入浅出《设计模式》之简单工厂模式(C++)
来源:cnblogs  作者:尔广强  时间:2019/7/19 9:01:05  对本文有异议

前言

模式介绍

简单工厂模式其实并不属于GoF23(23种设计模式),更类似工厂模式的一种变型。其定义是可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
这就有点像去饭馆吃饭,进了门和服务员说一句:“waiter!来一份海参炒面!” 一般情况下他只会给你海参炒面(不管里面有没有海参)。这会第二个人进来了,也喊了一句:“服务员,来一碗辣根汤面!”此时他就会给你一份辣根汤面。你们根本不会考虑海参炒面和辣根汤面咋炒的,只需要告诉店家,他就给你了。
上面实例中的“服务员”就是一个简单工厂。饭馆里的菜单就是简单工厂中的类列表。可以通过告知服务员点哪个类,服务员将类的实例也就是菜品端出来。这样对于我这个这个客户端来讲,没必要知道后厨做了什么,只需要拿到实例菜品吃就好了。如果终于有一天海参炒面变成了烧烤店,但是我也没必要知道后厨咋串的串儿,只需要进去还找服务员,要腰子就OK了。

UML类图

这里涉及到2种类,①我:客户端,负责调用服务员生成后端菜品实例。②服务员:工厂类,负责产生后端菜品并返回给客户端。③菜品:后端菜品类,生成的菜品。具体关系如下UML类图:

代码实例

下面是noodle类,是一个抽象类,里面具备一个eating函数,是为客户端准备的,食用。

  1. #ifndef NOODLE_H
  2. #define NOODLE_H
  3. class noodle {
  4. public:
  5. noodle() {}
  6. ~noodle() {}
  7. public:
  8. virtual void eating() = 0;
  9. };
  10. #endif // NOODLE_H

下面是海参炒面类,集成自noodle类,实现了eating方法:

  1. #ifndef HAISHENNOODLE_H
  2. #define HAISHENNOODLE_H
  3. #include "noodle.h"
  4. class haishennoodle : public noodle
  5. {
  6. public:
  7. haishennoodle();
  8. ~haishennoodle();
  9. public:
  10. virtual void eating();
  11. };
  12. #endif // HAISHENNOODLE_H
  1. #include <iostream>
  2. #include "haishennoodle.h"
  3. haishennoodle::haishennoodle()
  4. {
  5. }
  6. haishennoodle::~haishennoodle()
  7. {
  8. }
  9. void haishennoodle::eating()
  10. {
  11. std::cout << "我是海参炒面,里面没有海参哦!!吃的时候注意!" << std::endl;
  12. }

下面是辣根汤面类,继承了noodle类,重写了eating方法:

  1. #ifndef LAGENNOODLE_H
  2. #define LAGENNOODLE_H
  3. #include "noodle.h"
  4. class lagennoodle : public noodle
  5. {
  6. public:
  7. lagennoodle();
  8. ~lagennoodle();
  9. public:
  10. virtual void eating();
  11. };
  12. #endif // LAGENNOODLE_H
  1. #include <iostream>
  2. #include "lagennoodle.h"
  3. lagennoodle::lagennoodle()
  4. {
  5. }
  6. lagennoodle::~lagennoodle()
  7. {
  8. }
  9. void lagennoodle::eating()
  10. {
  11. std::cout << "我是辣根汤面,吃完呛的哼啊!!!" << std::endl;
  12. }

下面是服务员类,负责生成后端noodle。通过createnoodle生成noodle实例化,是工厂。

  1. #ifndef WAITER_H
  2. #define WAITER_H
  3. class noodle;
  4. class waiter
  5. {
  6. public:
  7. waiter();
  8. ~waiter();
  9. public:
  10. noodle *createnoodle(int type);
  11. };
  12. #endif // WAITER_H
  1. #include <iostream>
  2. #include "waiter.h"
  3. #include "haishennoodle.h"
  4. #include "lagennoodle.h"
  5. waiter::waiter()
  6. {
  7. }
  8. waiter::~waiter()
  9. {
  10. }
  11. noodle *waiter::createnoodle(int type)
  12. {
  13. noodle *n = NULL;
  14. switch(type) {
  15. case 0:
  16. n = new haishennoodle();
  17. break;
  18. case 1:
  19. n = new lagennoodle();
  20. break;
  21. default:
  22. std::cout << "对不起,我们这没有这个菜,请您换一个!" << std::endl;
  23. }
  24. return n;
  25. }

客户端代码如下,是我进店来点餐的步骤:

  1. #include <iostream>
  2. #include <string.h>
  3. #include "haishennoodle.h"
  4. #include "lagennoodle.h"
  5. #include "waiter.h"
  6. using namespace std;
  7. char *product_list[] = {
  8. "haishen-noodle",
  9. "lagen-noodle",
  10. NULL
  11. };
  12. int main()
  13. {
  14. char *p = NULL;
  15. char *pd = "haishen-noodle";
  16. int i = 0;
  17. waiter *w = new waiter();
  18. noodle *n = NULL;
  19. for(p = product_list[i]; p != NULL; i++, p = product_list[i]) {
  20. if(strncmp(pd, p, strlen(pd)) == 0) {
  21. n = w->createnoodle(i);
  22. if(n) {
  23. cout << "开吃!!!" << endl;
  24. n->eating();
  25. }
  26. }
  27. }
  28. if(n) {
  29. delete n; n = NULL;
  30. }
  31. if(w) {
  32. delete w; w = NULL;
  33. }
  34. return 0;
  35. }

附赠CMakeList.txt代码:

  1. cmake_minimum_required(VERSION 2.8)
  2. project(noodle)
  3. set(SRC_LIST main.cpp noodle.h lagennoodle.h lagennoodle.cpp haishennoodle.h haishennoodle.cpp waiter.h waiter.cpp)
  4. add_executable(${PROJECT_NAME} ${SRC_LIST})

编译运行结果

代码下载链接是:https://github.com/erguangqiang/freesir_headfirst/blob/master/noodle.tar.gz
使用cmake生成Makefile,并编译出可执行程序noodle。运行结果如下:

  1. erguangqiang@elab$./noodle
  2. 开吃!!!
  3. 我是海参炒面,里面没有海参哦!!吃的时候注意!

结束

使用简单工厂模式优点就是可以隔离客户端和实例化,这样客户端可以不理会类实例化的具体流程,达到了给客户端和逻辑解耦的目的。
但是简单工厂模式缺点也很严重,根据设计模式的开放-封闭原则,对于程序的扩展,不应改变类具体代码,可以对类集成扩展开放。一旦面馆出了新菜品,就需要修改工厂类。规避的方法是使用工厂模式,通过扩展的方式来实现。

原文链接:http://www.cnblogs.com/freeman2012/p/11206128.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号