项目开发日志(七) 模块逻辑解耦

(注:项目跨平台采用cocos2d-x,服务端 和 客户端游戏逻辑部分 采用C++,客户端UI部分采用Lua)

游戏项目一般模块众多功能庞杂,合理的逻辑解耦会让整个项目看起来结构清晰且易于维护,接口和事件是逻辑解耦的常用方式,C++和C#,JAVA不同 并没有明确的接口化编程,也没有像AS3那种功能完备事件处理,但C++是一种高度自由的语言,我们可以通过C++的继承与动态绑定来实现接口化.下面是我参与的项目中模块与模块的关系设计原型.

模块接口层图示

interface

把每一个项目都首先定义了一个接口,所有模块都可以通过接口管理来调用任意模块的内容.在模块的接口中由各个模块自己选择暴露什么内容给其他模块.例如我的战斗模块对其他模块暴露了对战斗速度的操作.

/**
 @brief 设置战斗总速度
 @param 
 @return
*/
virtual void    setFightSpeed(uint32 value) = 0;
//tolua_end

//tolua_begin
/**
 @brief 获取战斗总速度
 @param 
 @return
*/
virtual uint32  getFightSpeed() = 0;

接口能让模块选择性暴露东西给其他模块,这很好的实现了模块之间的封闭性.例如战斗模块实现了设置战斗速度的接口,则我们可以在任何一个模块去调用它,如果导出了给Lua,在Lua中也是可以的:

-- 在UI层逻辑模块中设置战斗速度
local speed = pFightSystem:getFightSpeed()
if speed == 1 then
    speed = 2
else
    speed = 1
end
pFightSystem:setFightSpeed(speed)

模块实现层图示

拿战斗模块来说,大概的原理图示应该如下:

fightsystem

继承上面的战斗接口,按照这个设计模式,每个模块都会有两部分:

  • 接口实现,提供给外部使用
  • 内部逻辑,处理内部数据逻辑

这种方式在繁杂的项目中管理模块会变得相对比较简单,而且后期会有一种写代码越来越快的感觉.

PS.我的语言表达能力值-5,更详细的请看DEMO:

Sample in my github