学习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 SDK,objc的alloc + 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》一书中推荐的一样,为每个类提供一个静态工厂方法来取代构造函数。

    

  

cocos2d-x中的二段构造模式的更多相关文章

  1. 6.在MVC中使用泛型仓储模式和依赖注入实现增删查改

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...

  2. 设计模式(九): 从醋溜土豆丝和清炒苦瓜中来学习"模板方法模式"(Template Method Pattern)

    今天是五.四青年节,祝大家节日快乐.看着今天这标题就有食欲,夏天到了,醋溜土豆丝和清炒苦瓜适合夏天吃,好吃不上火.这两道菜大部分人都应该吃过,特别是醋溜土豆丝,作为“鲁菜”的代表作之一更是为大众所熟知 ...

  3. Android中的创建型模式总结

    共5种,单例模式.工厂方法模式.抽象工厂模式.建造者模式.原型模式 单例模式 定义:确保某一个类的实例只有一个,而且向其他类提供这个实例. 单例模式的使用场景:某个类的创建需要消耗大量资源,new一个 ...

  4. MVC中使用泛型仓储模式和依赖注入

    在ASP.NET MVC中使用泛型仓储模式和依赖注入,实现增删查改 原文链接:http://www.codeproject.com/Articles/838097/CRUD-Operations-Us ...

  5. C++之二阶构造模式

    前言:C++中经常会因为调用系统资源失败导致出现BUG,所以在类调用构造函数需要分配系统资源时会出现BUG,从而导致类对象虽然被创建,但是只是个半成品,为了避免这种情况需要使用二阶构造模式 二阶构造模 ...

  6. C++解析(15):二阶构造模式

    0.目录 1.构造函数与半成品对象 2.二阶构造 3.小结 1.构造函数与半成品对象 关于构造函数: 类的构造函数用于对象的初始化 构造函数与类同名并且没有返回值 构造函数在对象定义时自动被调用 问题 ...

  7. 在C++11中实现监听者模式

    参考文章:https://coderwall.com/p/u4w9ra/implementing-signals-in-c-11 最近在完成C++大作业时,碰到了监听者模式的需求. 尽管C++下也可以 ...

  8. 【转】Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式

    [转]Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式 博客分类: 企业应用面临的问题 java并发编程 Struts2的线程安全ThreadLocal模式St ...

  9. 在MVC中使用泛型仓储模式和依赖注入实现增删查改

    标签: 原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository ...

随机推荐

  1. 【codeforces 508D】The Maths lecture

    [题目链接]:http://codeforces.com/problemset/problem/507/D [题意] 让你找符合这样数字的数的个数: 1.有n个数码 2.某个后缀%k的值为0 3.大于 ...

  2. fedora linux源代码下载

    yumdownloader --source kernel 如果是下载insight 就是 yumdownloader --source insight 下载到的是当前目录. 然后在用rpm2cpio ...

  3. bzoj2748: [HAOI2012]音量调节(背包)

    2748: [HAOI2012]音量调节 题目:传送门 题解: sb省选题..呵呵一眼背包: f[i][j]表示第i时刻能否为音量j 代码: #include<cstdio> #inclu ...

  4. 如何从 Datagrid 中获得单元格的内容与 使用值转换器进行绑定数据的转换IValueConverter

    一.如何从 Datagrid 中获得单元格的内容 DataGrid 属于一种 ItemsControl, 因此,它有 Items 属性并且用ItemContainer 封装它的 items. 但是,W ...

  5. kafka 0.11 spark 2.11 streaming例子

    """ Counts words in UTF8 encoded, '\n' delimited text received from the network every ...

  6. Linux就该这么学 20181004(第六章磁盘管理)

    参考链接https://www.linuxprobe.com/ /boot 开机锁需要文件-内核.开机菜单以及所需配置文件 /dev 以文件形式存放的任何设备与接口 /etc 配置文件 /home 用 ...

  7. xBIM 高级01 IFC多模型合并

    系列目录    [已更新最新开发文章,点击查看详细]  多模型合并可以实现以下功能: 覆盖多个模型以表现得像一个模型 统一访问数据,就像它是单个模型一样 只读.要修改模型的内容,您必须使用特定模型 不 ...

  8. Java7里try-with-resources分析--转

    原文地址:http://blog.csdn.net/hengyunabc/article/details/18459463 这个所谓的try-with-resources,是个语法糖.实际上就是自动调 ...

  9. java日期类型与字符串类型的相互转换

    package cn.zwq.convert; import java.text.ParseException; import java.text.SimpleDateFormat; import j ...

  10. Servlet学习(四)——response

    1.概述 在创建Servlet时会覆盖service()方法,或doGet()或doPost(),这些方法都有两个参数,一个是代表请求的request和代表响应response. service方法中 ...