设计模式在程序设计中会经常用到,也许你从来没有留意过设计模式,其实你却一直在使用设计模式!cocos2dx中有不少的设计模式,所以从本篇博客开始探讨一下cocos2dx中的设计模式,看看引擎都使用了哪些设计模式,我们今后写代码要怎样使用某种设计模式。
大家最熟悉的是单例设计模式了吧,在cocos2dx中单例真是不少啊,我们的大导演不就是单例吗,单例设计模式我之前写过一篇博客,这里就不多说了。第二个设计模式是观察者模式,什么是观察者模式,如何实现观察者模式。就是被观察者含有一个数组,里边存放了所有观察者的引用,在被观察者的状态发生改变的时候,通过调用观察者的函数来通知观察者,实现了信息的传递。之前也有一篇博客写了cocos2dx中用来实现观察者模式的事件监听器NotificationCenter,大家可以看看。本篇博客探讨一下二段构建模式,首先第一个问题是什么是二段构建模式。
大家都知道在c++中我们一般在构造函数中为对象分配内存空间然后初始化成员变量,比如我们调用了new某个东西,那么在堆上会先为对象分配内存空间,然后调用构造函数,在构造函数中完成一些初始化的工作。而二段构建模式就是将内存空间的分配和初始化分开来完成,然后调用一个静态方法来返回这个对象。就拿cocos2dx中的Sprite类来说吧,当我们调用Sprite::create()的时候内部先使用new来分配内存空间,然后调用init方法来初始化一些变量的设置。所以cocos2dx中的二段构建模式就是将new分配内存空间和init初始化内容分开来处理,而不是c++传统的做法在构造函数中初始化变量。
1 |
Sprite* Sprite::create() |
4 |
Sprite *sprite = new Sprite();
|
6 |
if (sprite && sprite->init())
|
12 |
CC_SAFE_DELETE(sprite);
|
上边就是使用二段构建模式的过程,Sprite首先调用new来分配内存空间,然后调用init函数来完成初始化的工作,顺带还做了内存管理的工作,最后返回初始化好的对象。所以看了Sprite的create方法的实现,我们也知道了应该怎么使用这个二段构建模式了吧。
第二个问题是为什么要这么用,对于c++程序员来说初始化工作不都是在构造函数中完成的吗,cocos中为何要这么做呢?这里引述一下王哲的话:“其实我们设计二段构造时首先考虑其优势而非兼容cocos2d-iphone. 初始化时会遇到图片资源不存在等异常,而C++构造函数无返回值,只能用try-catch来处理异常,启用try-catch会使编译后二进制文件大不少,故需要init返回bool值。Symbian, Bada SDK,objc的alloc + init也都是二阶段构造”。现在大家明白了吧,兼容cocos2d-iphone是一个原因,另一个重要的原因是构造函数没有返回值啊,如果加载资源图片的时候不存在怎么办,所以初始化的工作写在init函数中,这个函数返回的bool值用来判断是否初始化成功。使用这种方法还可以强化设计,想想自己写代码的时候是不是因为没有初始化某个成员变量导致了bug,这样做就是提醒你记得要在init中初始化成员变量。通过create静态函数返回的这个对象也实现了cocos2dx中的内存管理,就不用我们自己麻烦了。还有一个原因是在c++的构造函数中是不能调用虚函数的,为了调用虚函数来完成一些功能就要写在init函数中。
以上就是二段构建模式的说明了,在我们写cocos程序的时候其实不知不觉就已经在使用这个构建模式了,想一下我们一个类继承了Layer,然后使用了宏CREATE_FUNC(),这不就是create静态方法吗,在init函数中完成了初始化,整个过程就是在用这种设计模式!