前言

这本书忘记从哪里下载了,和别的技术书籍不太一样,大多的内容都比较贴合项目开发,所以有一定的参考价值。

里面有几个章节觉得有收获的,主要是框架的设计,以及一些解决问题的思路,大致做了笔记或者摘录。

一、基础内容交流

代码规范

可读代码:由于动态语言的类型灵活性,可以在变量前加上变量类型简称

正确使用断言与返回

注意什么时候可以为空,不要盲目返回

可拓展接口使用

多参数,下面演示了三种写法,最终应该在保留必要参数的情况下,可选参数做成table

addModulePower(nModuleId, nPower);
addModulePower(nModuleId,nPower,bSyncMsg,bSendEvent, bOnlyBoss)
if( tOption && tOption.bSyncMsg){
//做这个参数该干的事情
}

调试的思维与逻辑

  1. 正向和逆向思维,逆向更快
  2. 不易复现的bug,埋下日志,下次使用

培养敏锐的异常反应

注意生命周期的创建与销毁

代码修改与重构

我们在项目中秉持一个原则,如果有个接口让你不舒服,比如说多传了几个参数,那么我们一定要提出来,那一定是接口的设计不够简单或者没有提供更简单的接口形式。

优雅的使用外部代码

  1. 我们的一个原则就是要尽可能少去直接和引擎进行交互,而是更多的进行局部缓存,把战场拉回到更加通用的逻辑里面。
修改后的代码为:
let levelSlider = Core.createBitmapByName("slider_png");
let nSliderX = 0;
if(XXX){
nSliderX += 6;
}
if(XXX){
nSliderX += 8;
}
if(XXX){
nSliderX -= 2;
}
levelSlider.x -= nSliderX;
  1. 选择简单的接口/参数以及尽量少的使用/调用底层接口就是我们所谓的正确的代码使用方式。

代码审查

取出一个管理器对象。然后直接访问了它的成员函数,这是非常不应该行为。第一个是这个成员不应该是公有的,而应该是私有的,它的公有性质破坏了类的封装。

从面试的角度看面试

基础能力,逻辑能力,硬核能力

如何应对代码错误

作为项目的主程,还需要统一思想。这个过程包括要求大家遵循统一的代码命名等,这也是规避错误的一个重要手段。越是相似的代码风格,代码的阅读速度就会越快。

二、逻辑设计模式式讨论

分层设计

  1. 事件的派发遵循从下往上:比如M驱动V
  2. 依赖性越强的越靠下层
  3. 变化的放上层,底层可以互相依赖,逻辑层不允许相互依赖

主动和被动

  1. 被动模式,依赖事件,及时,性能消耗少,当被动模式不在能支持复杂逻辑时,可以考虑主动模式
  2. 主动模式,依赖轮询,有点像ESC的系统层监听实体层的感觉了。优点在于可以监听多种条件

阻塞和非阻塞

主要用于资源加载,阻塞速度快

统一与非统一

效率没有打到一定程度的影响时,推荐考虑统一性

三、框架设计初步

基类

存活状态,唯一ID

框架代码结构

子类关注的基类接口一定是个空的实现,意味着子类不需要考虑去调用父类同名的接口。

框架设计

  1. 配置化编程:消除重复代码,如协议监听,按钮监听等等
  2. 自动化平衡处理:如果没有销毁,帮忙擦下屁股
  3. 机制有助于实现全局性的功能,尤其处理大规模需要重复代码的东西

框架拓展的思路

基础能力,封装类,继承到框架中

四、逻辑设计原理

缓存的设计

  1. 缓存存放的东西有限,不能所有的东西都放缓存。
  2. 缓存应该具备清理功能。
  3. 缓存系统应该具备一定的匹配能力。
  4. 缓存具备最小保留数量以及预先创建的能力

分线漫谈

分线,是将玩家划分到不同的频道中,不同频道的玩家互不可见,且不会互相同步消息。分线在程序方面主要用于减少网络包,在策划层面会有一些其他的应用。分线是基于场景的,我们的可见性,以及消息同步默认以场景为单位。

五、细节与其他

代码管理

大型项目中会遇到一种代码管理模式,基于分层的思想。底层代码会在一个代码库中,项目上层代码会在一个代码库,项目工具代码会在一个代码库。三个代码分别检出构成最终的项目。

检测与转换

配置检测主要是检测表与表之间的关联性,检测是否存在重复id行,检测值的范围是否正确。

异常处理

我们需要先划分最小的异常范围,然后在进行少量的异常捕获,在捕获后需要把异常的对象清理掉。这就是整个异常处理的过程。这里需要掌握的是核心的处理方式,就是我们怎么样可安全的处理好一个不确定性能的代码。

try{
//干第一件事
nIndex = 1;
//干第二件事
nIndex = 2;
//干第三件事
nIndex = 3;
}catch{
swtich(nIndex){
case 0:
break;
case 1:
break;
case 2:
break;
}
}

六、商业环境问题

程序负责人的关注

微观: 配置的定义 存储的数据结构定义 通信协议的定义 服务器,客户端模块通用部分的抽离客户端界面公共部分抽离 细节难点的处理

宏观: 内存的稳定 CPU的稳定 网络包量的稳定 程序本身的稳定 兼容性问题 综合: 资源的规划 设计的决策 代码规范的确立 后台(php)交互方式制定

报警机制

我们来看看什么情况需要报警。服务器短时间内多次重启需要报警,这种属于比较大的清晰可见的情况。往内一点讨论,当玩家存储的数据存储失败的时候,不一定需要报警。而当多个玩家出现这个情况时,就需要报警了。逻辑本身可能是会发生错误的,但是这种错误可小可大,我们不需要每个错误都去报警,这样会干扰我们正常的开发。我们尝试再加入触发次数这样的条件来定义一个报警事件。当多个玩家在一段时间内发生了多次值得报警的bug的时候,比如存储数据失败,登录失败,充值失败,在游戏中无法移动等情况,我们都可以进行报警。报警采用的游戏处理手段可以是停止新玩家登录,也可以是关服等。

游戏更新

服务端的更新与客户端的更新如何同时生效,使用版本管理

需要同时生效是因为服务端和客户端都可能更新配置,而配置我们希望是两端读到的都是一样的。服务端的更新我们可以做到瞬间就能生效,但是客户端的代码资源都是放在CDN上,更新生效的时间是不一定的。那么我们可以看到的是同时生效的难题在于客户端资源的生效时间是不确定的。我们需要引入资源的版本机制,就像前面说的缓存更新一样。我们在CDN生效之后,再更新服务端,继而切换资源的版本号,通过这样来达到它们的同时生效。