cocos2d-x设计模式发掘之五:防御式编程模式

分类: Cocos2d-x 2013-04-10 02:58 342人阅读 评论(0) 收藏 举报

本文由子龙山人原创,转载请注明出处并通知子龙山人!

声明:防御式编程是提高程序代码质量的一种手段,它不能算是真正意义上的模式。但是,这里,我还是要给它冠之以“模式”二字。

原因有2:
1.cocos2d-x的框架源代码大量采用了防御式编程技术,用来确保框架的代码质量和稳定性。

2.标题党,引起大家对于防御式编程的重视。特别是当大家给cocos2d-x贡献源代码的时候,更应该要注意保证代码质量。因为,王哲大大在review很多人给cocos2d-x贡献代码时发现,这种防御式编程代码并不多,需要引起我们的注意。

1.应用场景
首先,第一个大量使用的是CCLayer的init函数:

  1. boolCCLayer::init()
  2. {
  3. bool bRet =false;
  4. do
  5. {
  6. CCDirector* pDirector;
  7. CC_BREAK_IF(!(pDirector =CCDirector::sharedDirector()));
  8. this->setContentSize(pDirector->getWinSize());
  9. m_bIsTouchEnabled =false;
  10. m_bIsAccelerometerEnabled =false;
  11. // success
  12. bRet =true;
  13. }while(0);
  14. return bRet;
  15. }

这里使用了do…while(0);惯用法,同时配合CC_BREAK_IF宏来做错误处理。关于为什么要使用do…while(0)惯用法,可以参考这篇文章:

另一个地方就是一些内存管理的宏,这些宏可以帮助我们编写更健壮的内存管理代码:

  1. #define CC_SAFE_DELETE(p)do{if(p){delete(p);(p)=0;}}while(0)
  2. #define CC_SAFE_DELETE_ARRAY(p)do{if(p){delete[](p);(p)=0;}}while(0)
  3. #define CC_SAFE_FREE(p)do{if(p){ free(p);(p)=0;}}while(0)
  4. #define CC_SAFE_RELEASE(p)do{if(p){(p)->release();}}while(0)
  5. #define CC_SAFE_RELEASE_NULL(p)do{if(p){(p)->release();(p)=0;}}while(0)
  6. #define CC_SAFE_RETAIN(p)do{if(p){(p)->retain();}}while(0)

最后一个地方,就是在函数的入口处,或者需要保证某些“不变量”的时候,使用assert断言来确保参数和返回结果的有效性。这个在cocos2d-x的源代码中也到处是可以看到的。

2.使用此模式的优缺点

优点:
提高代码质量,使得代码的健壮性和稳定性都有保障。可以防止子程序由于接收到了非法数据而遭受破坏。

缺点:
过度的防御式编程也会引来问题,如果你在每一个能想到的地方用每一种能想到的方法检查从参数传入的数据,那么你的程序将会变得臃肿而缓慢。更糟糕的是,防御式编程引入的额外代码增加了软件的复杂度。所以运用是需谨慎。

3.此模式的定义及一般实现
子程序应该不因传入错误数据而被破坏,哪怕是由其他子程序产生的错误数据。

我们一般可以采用以下手段来进行防御式编程:

1)检查每个子程序的入口参数,记住“垃圾进、垃圾出”这个隐喻。必要的时候可以使用断言来确保函数的先验条件是符合假定的。因为很多时候,我们编写代码都是隐藏了一系列的假定的,只是你自己没有感觉到,有时候,这些假定没有关系,出了bug也容易找出来。但是,有时候,就不是那么幸运了。

2)不要直接使用文字常量,比如3、“Hero.png”这种常量。尽可能地定义const定义常量或者使用宏定义。

3)尽可能让函数返回一些东西,这样如果当函数运行出现问题时,可以根据返回值做一些处理。如果全部设计成void类型的函数,那么出现异常要么就是try—catch,要么就是直接让程序崩溃了。由于c++的异常机制并不是那么完善,所以,也一直为人们所诟病,cocos2d-x里面几乎没有使用c++的异常处理机制。最后,必要的时候要检查函数里面调用其它子程序时的返回值。

4.实际开发中如何采用此模式
在实际开发中,我个人觉得必要的防御式编程的态度和做法还是要有的。特别是函数的输入输出,因为函数的逻辑部分是我们关注地最多的,虽然它是最复杂的,但是,往往这部分出错的概率不高。

相反,是函数的一些边界条件和异常情况导致程序bug的滋生。有些时候除了验证函数参数的数据值范围有效性以外,更加要注意的是验证数据的业务条件是否满足。这一点恰恰最容易被忽视。

在做内存管理的时候,尽可能地使用cocos2d-x里面定义的一些宏来清理资源,比如CC_SAFE_DELETE等。当实现自定义的CCLayer对象的时候,也尽可能地采用do…while(0)的写法,如果里面出现问题,可以用CC_BREAK_IF来判断并退出。

5.此模式与其它模式的关系
暂不讨论

转载于:https://www.cnblogs.com/wodehao0808/p/3374517.html

cocos2d-x设计模式发掘之五:防御式编程模式相关推荐

  1. Cocosd-x”设计模式“之五 :防御式编程”模式“

    这一篇将来学习防御式编程模式,其实它并不是一种标准的设计模式,使用它主要是为了提高程序的健壮性,其实这是软件开发中一个我们必须熟悉的模式,因为在程序代码中,很多地方往往存在一定的不确定性,如果我们对于 ...

  2. C/C++ 踩过的坑和防御式编程

    相信你或多或少地用过或者了解过 C/C++,尽管今天越来越少地人直接使用它,但今天软件世界大多数软件都构筑于它,包括编译器和操作系统.因此掌握一些 C/C++ 技能的重要性不言而喻. 这场 Chat ...

  3. 软件构造-犯错的艺术——健壮性与正确性,异常,防御式编程,debugging与test的思考与总结...

    健壮性与正确性 健壮性与正确性是不同的--一个倾向于使程序尽可能保持运行,即使遇到错误,一个倾向于使程序尽可能正确,不在意保持运行 异常 异常分为两种--checked exception与unche ...

  4. 6-3 断言与防御式编程

    一.ADT的设计 静态检查.动态检查.使用不可变的类型.值.引用等都有助于减少bug. bug是不可能完全避免的,要将bug限定在一个小范围内,使得程序尽早出问题.例如下图,前置条件要求x>=0 ...

  5. 编程范式:函数式编程防御式编程响应式编程契约式编程流式编程

    不长的编码生涯,看到无数概念和词汇:面向对象编程.过程式编程.指令式编程.函数式编程.防御式编程.流式编程.响应式编程.契约式编程.进攻式编程.声明式编程--有种生无可恋的感觉. 本文试图加以汇总和整 ...

  6. Defensive Programming 防御式编程(Defensive Programming)

    Defensive Programming 防御式编程(Defensive Programming)是提高软件质量技术的有益辅助手段 怎么理解呢?防御式编程思想的理解可以参考防御式驾驶: 在防御式驾驶 ...

  7. 华山论剑之契约式编程与防御式编程

    背景 事情的来由还要从几十几亿年前的一次星球大爆炸说起,sorry,背错台词了,是从几天前讨论接口返回数据和几个月前讨论课件本地数据结构说起,简单的说,就是碰到约定好的内容出现异常,是我们在程序中内部 ...

  8. 契约式编程与防御式编程

    背景 事情的来由还要从几十几亿年前的一次星球大爆炸说起,sorry,背错台词了,是从几天前讨论接口返回数据和几个月前讨论课件本地数据结构说起,简单的说,就是碰到约定好的内容出现异常,是我们在程序中内部 ...

  9. 关于防御式编程 (Defensive programming )和安全编码

    目录 1. 啥是防御式编程? 2. 防御式编程的目标 3 防御式编程的好处 4 防御式编程带来的负面影响 5. secure programming 5.1 secure programming安全编 ...

  10. 7.3Assertions and Defensive Programming断言与防御式编程

    7.3Assertions and Defensive Programming断言与防御式编程 1.回忆:设计ADT 2.Assertions 声称 --What to Assert and What ...

最新文章

  1. 如何在vsc上选择远程miniconda特定的虚拟环境中的Python解释器(4步)
  2. 使用sudo进入root权限,以及防止root密码被恶意篡改
  3. java 观察者模式
  4. Android系统启动流程分析之安装应用
  5. linux网络管理技术,linux网络管理 一
  6. 计算机系统基础:输入输出技术知识笔记
  7. windows系统下oracle数据库rman备份记录(实战篇)
  8. QQ 一键加群、扫二维码加群 - 腾讯官方API文档接入
  9. 一文带你了解什么是GitOps
  10. 百度网盘欲分拆闯关科创板?
  11. 腾讯二面:@Bean 与 @Component 用在同一个类上,会怎么样?
  12. 文远知行发布自动驾驶新方案:日产纯电动车型,搭载性价比激光雷达
  13. oracle 没有rlwap,[20140723]安装使用anysql.txt
  14. Objective-C与Swift下的自定义打印函数(Debug和Release)
  15. 【TSP】基于matlab自重启伪遗传改良算法求解旅行商问题【含Matlab源码 1510期】
  16. 2014中国十大管理实践-世界经理人网站
  17. 百度编辑器 教程 ueditor
  18. 20sccm_SCCM安装及配置过程总结
  19. 关于利用Klayout查看GDS需要导入工艺库的layer properties file(.lyp)
  20. React之Dva的学习

热门文章

  1. CYQ.Data 轻量数据访问层(七) 自定义数据表实现绑定常用的数据控件(上)
  2. 《刺猬的优雅》观后感
  3. java里程碑之泛型--使用泛型
  4. 利用ldirectord实现lvs后端realserver健康状态检查
  5. Shiro(一)——Shiro概述
  6. Android-Studio 缓存文件夹配置
  7. Luogu4198 楼房重建
  8. [2018.03.14 T3] 圈圈(cyclic)
  9. spark保存数据到hbase_Spark读取Hbase中的数据
  10. python time函数的功能_Python中Python时间模块的常用功能,Pythontime,函数