免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4941 | 回复: 8
打印 上一主题 下一主题

[C++] factory 模式有何优点? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-08-23 20:12 |只看该作者 |倒序浏览
去封装一个 new 感觉很S13啊
直接 new 不是挺好

论坛徽章:
5
技术图书徽章
日期:2013-11-07 13:21:58技术图书徽章
日期:2013-12-07 10:34:46技术图书徽章
日期:2014-04-23 08:50:31双鱼座
日期:2014-09-16 09:12:34亥猪
日期:2015-01-23 13:37:49
2 [报告]
发表于 2011-08-23 20:34 |只看该作者
各有自己的适用范围。

牛顿力学还只适用于低速宏观呢。看问题还要看情况:环境。

论坛徽章:
0
3 [报告]
发表于 2011-08-23 21:07 |只看该作者
比如什么环境?

论坛徽章:
1
摩羯座
日期:2013-11-14 15:56:09
4 [报告]
发表于 2011-08-25 10:26 |只看该作者
为了提高内聚(Cohesion)和松耦合(Coupling),我们经常会抽象出一些类的公共
接口以形成抽象基类或者接口。这样我们可以通过声明一个指向基类的指针来指向实际的子
类实现,达到了多态的目的。这里很容易出现的一个问题n多的子类继承自抽象基类,我们
不得不在每次要用到子类的地方就编写诸如new ×××;的代码。这里带来两个问题1)客
户程序员必须知道实际子类的名称(当系统复杂后,命名将是一个很不好处理的问题,为了
处理可能的名字冲突,有的命名可能并不是具有很好的可读性和可记忆性,就姑且不论不同
程序员千奇百怪的个人偏好了。),2)程序的扩展性和维护变得越来越困难。

论坛徽章:
0
5 [报告]
发表于 2011-08-25 10:28 |只看该作者
当你有五十种东西要new,而且都是一个继承树下的,而且new完了都需要做同一种初始化和配置操作的时候,你不用factory用什么

论坛徽章:
0
6 [报告]
发表于 2011-08-25 10:29 |只看该作者
类数量多了,还是有好处的;否则,爱用不用~~

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
7 [报告]
发表于 2011-08-26 09:27 |只看该作者
o(︶︿︶)o 唉。
不是new的数量多少的问题。

比如工厂方法模式,是将实例化延迟到子类。这样,在基类中完成逻辑的时候,只使用基类类型。而真正的类型,由工厂方法返回。

论坛徽章:
1
射手座
日期:2013-08-21 13:11:46
8 [报告]
发表于 2011-08-26 10:20 |只看该作者
Factory只是配合接口使用的,没有接口,要Factory做啥子

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
9 [报告]
发表于 2011-08-26 10:26 |只看该作者
本帖最后由 captivated 于 2011-08-26 13:06 编辑

回复 1# cjxgm


    举个例子吧,简单工厂。请注意,简单工厂不是GOF的23种设计模式之一。GOF的23种设计模式中,有两种关于工厂的模式,是工厂方法模式和抽象工厂模式。简单工厂和工厂方法模式不可混为一谈,但是都用到了工厂方法。

    假设你开个汉堡店。
    你写了一个汉堡基类 -- 因为有辣鸡翅汉堡、有甜圈汉堡、有咸鱼汉堡等等。
    完成一个汉堡,有原材料准备prepare、烘烤bake、以及包装package等过程。所有的汉堡制作都要经历这个过程。这些方法在基类中声明。所有的汉堡类都继承并Override这些方法。

    现在你要写一个订购汉堡的函数,如果有客户要订购汉堡,调这个订购函数就可以了。问题是有各种各样的汉堡。于是,根据汉堡的类型,你需要new不同的汉堡。但是,除了new之外所有的代码都是一样的:原料准备,烘烤,包装。只要知道是什么类型的汉堡,那种类型的汉堡就知道怎么完成整个过程(嗯,虚函数)。
  1. void order_hamburger(string& HB_type)
  2. {
  3.     Hamburger* hb;
  4.     if (HB_type == 辣鸡) {
  5.         hb = new 辣鸡汉堡;
  6.     } else if (HB_type == 咸鱼) {
  7.         hb = new 咸鱼汉堡;
  8.     } else if () {
  9.         ...
  10.     }

  11.     hb->prepare();
  12.     hb->bake();
  13.     hb->package();  
  14. }
复制代码
你写了一大堆if else。这可不好,一旦汉堡的种类有变化,你就得重新维护order_hamburger方法。不止order_hamburger,还有类似于order_hamburger这种根据类型来判断new什么对象的方法 -- 你都需要重写。可能复制粘贴是个好办法...

    稍微好一点的,就是写一个工厂类,里面放一个工厂方法:
  1. class HBFactory {
  2.   Hamburger* createHB(string& HB_type)
  3.   {
  4.       Hamburger* hb;
  5.       if (HB_type == 辣鸡) {
  6.          hb = new xxx;
  7.       } else if ( ) {
  8.          ...
  9.       }
  10.          ...
  11.       return hb;
  12.   }
  13. };
复制代码
这样,order_hamberger就可以这样写了:
  1. order_hamburger(string& HB_type)
  2. {
  3.     HBFactory HBfactory;
  4.     Hamburger* hb = HBfactory.createHB(HB_type);

  5.     hb->prepare();
  6.     hb->bake();
  7.     hb->package();  
  8. }
复制代码
order_hamburger方法永远不需要变动。一旦有改变,改变那个Factory就可以了。

    你说,这不过是把if-else移到HBFactory里面而已。没错,只是类似于order_hamburger的方法都可以使用这个工厂,所以避免了代码重复。所有的if-else变化,都统一放到这个工厂类的工厂方法里了。
    这使得,代码可能变化的部分被独立出来。独立到这个工厂类中了。设计模式中所谓“封装变化”,就是指将变化的部分独立出来,这样一旦有变化发生,改动一处就可以了,而不是处处复制粘贴,一旦疏忽就出错。

    嗯,上面的就是简单工厂类了(不是GOF收录的设计模式,只是常用而已)。工厂方法模式,就是在基类中定义一个工厂方法,所有的继承类都重写这个工厂方法,由子类来决定究竟实例化哪一个。抽象工厂模式,则可以创建交叉的产品族。

    o(︶︿︶)o...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP