容易忽略的多条件状态问题
作者 佚名技术
来源 服务器技术
浏览
发布时间 2012-07-07
今天检查游戏引擎代码时发现一个不怎么起眼却会影响整个系统的问题,最终用了一个简单的方式做了了结。 这个问题在这里暂时称之为“多条件状态问题”。 我们常常会有这样一种需求,某个事件触发的前提有多个操作,每个操作都是一个独立的行为。那么为了让我们的代码更加优雅,我们通常把每一个操作封装成一个独立方法。然后再用一个方法来调用这些独立的方法,最后发出一个完成的事件。 为了更加准确的理解,我们可以想象现在我们要发射一枚运载火箭,假定发射前我们需要做一些准备才能发射。 1、电力系统检查 2、通讯系统检查 3、分离器检查 4、加注主推进燃料 5、加注辅助推进器燃料 最后通知准备完毕——点火。 用程序简单表示一下: public function 发射初始化() { 电力系统检查(); 通讯系统检查(); 分离器检查(); 加注主推进燃料(); 加注辅助推进器燃料(); dispatchEvent(new Event("发射就绪")); } private function 电力系统检查() { …… } private function 通讯系统检查() { …… } private function 分离器检查() { …… } private function 加注主推进燃料() { …… } private function 加注辅助推进器燃料() { …… } 写完之后感觉流程清晰,代码优雅。看起来貌似没有问题了,而且也确实在大多数情况下你几乎看不出有什么问题。 然而真的是这样吗??? 仔细分析,你会发现由于我们把繁琐的方法封装到了一个个独立的方法里面。尽管在方法的执行上,他是顺序的。但是你却忽视了至少两点: 第一点:方法被依次执行,但是并非是我们想象的第一个方法执行完才执行第二个,而是第一个执行后开始执行下一个。 换句话说第一个方法开始后,没有等到结束第二个就开始了,然后第三个、第四个。。。这与我们所期望的是完全背离了。 第二点:或许“准备就绪”的事件已经发出了,而我们上面的各个发射准备却还在进行。这相当恐怖了。 那么为什么很多时候我们测试的时候我们发现不到呢?因为我们的各个独立方法中的逻辑并不复杂不属于耗时操作,所以“准备就绪”事件发出后,点火程序执行时正好前面的准备完毕了。所以火箭顺利发射出去。 解决方案: 现在我们知道了问题的所在,你一定开始想办法解决了。最简单的方式我们可以吧这个过程改成顺序执行的,即一个条件完成之后再进行下一个(有点像自己分配运行时间片段)。继续拿发射火箭举例,就好像总指挥喊话: “检查电力系统” “电力系统检查启动。。。动力系统检查完毕!” “检查通讯系统” “通讯系统检查启动。。。通讯系统检查完毕!” 。。。。。。 “所有检查完毕,可以发射” “点火——” 我们还可以用另一种方式来实现,使用非顺序的事件通知的方式解决。怎么理解? 现在,总指挥面前出现了5个开关,只有5个开关都打开,点火按钮才可以按下。现在的口令模拟一下如下: “开始发射准备” “电力系统一切正常” 总指挥打开1号开关 “通讯系统一切正常” 总指挥打开2号开关 “主推进燃料加注完毕” 总指挥打开4号开关 “辅助推进燃料加注完毕” 总指挥打开5好开关 “分离系统检查完毕,一切正常” 分离系统检查需要花比较长时间,这个时候才完成。总指挥打开3号开关 5个开关都打开,此时总指挥“准备完毕,点火”,按下了点火按钮。 非顺序方式的好处 比较一下上面的两种方式,你会发现非顺序的通知方式或许更加容易扩展,因为我们只要加一个开关就行了。 按照上面的思路,我们用二进制的每一位来表示一个开关,二进制的位上为1表示这个条件已经满足。程序我们这样来写。 private var status:int; public function 构造函数() { addEventListener("准备就绪",火箭准备); …… } public function 发射初始化() { 电力系统检查(); 通讯系统检查(); 分离器检查(); 加注主推进燃料(); 加注辅助推进器燃料(); } private function 电力系统检查() { …… status=status|1 dispatchEvent(new Event("准备就绪")); } private function 通讯系统检查() { …… status=status|2 dispatchEvent(new Event("准备就绪")); } private function 分离器检查() { …… status=status|4 dispatchEvent(new Event("准备就绪")); } private function 加注主推进燃料() { …… status=status|8 dispatchEvent(new Event("准备就绪")); } private function 加注辅助推进器燃料() { …… status=status|16 dispatchEvent(new Event("准备就绪")); } private function 火箭准备() { if(status&31) dispatchEvent(new Event("点火")); } 关键词:条件 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |
你可能对下面的文章感兴趣
上一篇: Flash CS3仿真艺术设计系列之模糊滤镜的应用实例下一篇: 怎样使代码优化的更好
关于容易忽略的多条件状态问题的所有评论