学习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. Ruby print

    Ruby print

  2. mybatis批量插入oracle大量数据记录性能问题解决

    环境: mybatis  + oracle11g r2 1.使用"直接路径插入"(以下sql语句中的"/*+append_values */"),而且使用key ...

  3. Oracle在更改机器名后服务无法启动的解决方法

    Oracle改变机器名后会导致服务无法正常启动,能够通过下列操作解决: 1.oracle\product\10.2.0\db_3\network\ADMIN文件夹下,listener.ora文件里的L ...

  4. 一个build.xml实例

    <?xml version="1.0"?> <project name="ssh" basedir="." default ...

  5. C++ Primer Plus的若干收获--(九)

    这篇博文我接着上一篇来写,相同讲一些关于类的一些基础知识. 本篇将会继续使用上篇的股票类STock,这里给出接口 ifndef STOCKOO_H_ #define STOCKOO_H_ #inclu ...

  6. BZOJ 1007: [HNOI2008]水平可见直线 平面直线

    1007: [HNOI2008]水平可见直线 Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则 ...

  7. 利用wget 抓取 网站网页 包括css背景图片

    利用wget 抓取 网站网页 包括css背景图片 wget是一款非常优秀的http/ftp下载工具,它功能强大,而且几乎所有的unix系统上都有.不过用它来dump比较现代的网站会有一个问题:不支持c ...

  8. hdoj--1010--Tempter of the Bone(搜索+奇偶剪枝)

    Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe ...

  9. systemd服务管理---systemctl命令列出所有服务

    1.列出系统所有服务 #systemctl list-units --all --type=service

  10. CentOS7安装第三方yum源EPEL

    转自:https://blog.csdn.net/u012208775/article/details/78784616 一.简介 EPEL是企业版 Linux 附加软件包的简称,EPEL是一个由Fe ...