cocos2d-x中的二段构造模式

    学习cocos2d-x的过程中,会发现许多对象都通过一个静态函数create来创建。比如下面的一个例子
#define CREATE_FUNC (__TYPE__) \
static __TYPE__* create() \
{ \
    __TYPE__ *pRet = new __TYPE__(); \
    if (pRet && pRet->init()) \
    { \
        pRet->autorelease(); \
        return pRet; \
    } \
    else \
    { \
        delete pRet; \
        pRet = NULL; \
        return NULL ; \
    } \
}


查看源代码可以知道这里有一个通用的create函数,它主要的功能是创建实例,通过new实现,然后进行初始化,通过init()来实现,并添加一个autorelease()来实现回收机制。一开始觉得挺别扭,因为构造函数本来就是用于创建并初始化实例的,这样做有点多此一举,或者是一种代码风格,不能理解,上网查完之后才知道原来这种风格有一个名字叫做二段构造模式。

cocos2d-x的作者王哲对于这个问题的解答是“其实我们设计二段构造时首先考虑其优势而非兼容cocos2d-iphone. 初始化时会遇到图片资源不存在等异常,而C++构造函数无返回值,只能用try-catch来处理异常,启用try-catch会使编译后二进制文件大不少,故需要init返回bool值。Symbian, Bada SDKobjcalloc + init也都是二阶段构造”。把分配内存与初始化分开,有利于调试初始化出现的一些问题。而构造函数把内存分配和初始化一并完成,难以把两种阶段分离开来,给调试带来一定的不便。除了这个初衷,应该有一部分原因是因为cocos2d-x是由cocos2d-iphone衍生而来,为了保持代码风格一致,而留下这种创建对象的方式。(因为object-c中是没有构造函数这种概念),同时也方便代码移植到iPhone平台上,而且也方便-x-iphone的程序员能够迅速转换吧。

看了子龙山人一文《Cocos2d-x设计模式发掘之二:二段构造模式》,更是进一步了解到其实这种方法把内存分配与初始化分离,可以说是一种设计强化,因为我们往往在创建对象后忘记初始化,这种bug经常发生,现在二段构造的模式强调了初始化工作。

说到这里,其实才发现这个问题的本质是构造函数和静态工厂方法两种方式创建对象的比较。

采用构造函数实例化对象是语言的规范,用这种方法比较直观。而采用静态工厂方法则有以下3个有点:(参考http://blog.csdn.net/cgwshxs/article/details/3455136

1、构造方法的名字必须与类名相同。而静态工厂方法的方法名可以是任意的,这一特性的优点是可以提高程序代码的可读性,在方法名中能体现与实例有关的信息。

2、每次执行new语句时,都会创建一个新的对象。而静态工厂方法每次被调用的时候,是否会创建一个新的对象完全取决于方法的实现。

3、静态工厂方法可以返回当前类的子类的实例,这一特性可以在创建松耦合的系统接口时发挥作用。

虽然静态工厂方法有这些优点,但是当对象的构造方法是私有或者default时,这种方法就不能创建该对象了。而且静态工厂方法和其他静态方法从名字上看无法区分。

在通常的情况下,利用构造函数还是最直接的方法,但是当条件允许,使用静态工厂方法也是明智之举。就如在《Effivtive JAVA》一书中推荐的一样,为每一个类提供一个静态工厂方法来代替构造函数。

    

  


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值