让模块接口化

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

(注:项目跨平台采用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

《让模块接口化》有2个想法

  1. 这种设计在AS3那边一直在用,只是模块被称之为系统,例如:战斗系统、社区系统、ui系统等等。
    C++这边之前有尝试过,觉得C++本来的.h和.cpp就让代码足够冗余了,如果还加上这么一层的话,到项目后期代码文件数量太多,不方便管理。(我现在的项目也是C++ lua来解决)
    另外,最近一直在寻找\组合比cocos2dx更轻量更人性化的一些东西,希望多交流。

    1. @timoo, .h和.cpp就让代码足够冗余?额,如果你觉得把头文件和实现文件分开不习惯,那可以把实现也写在.h文件里面..C++都支持的,只不过这种方式在有些编译器中会起了”隐喻”内联函数的作用.我的项目中使用大量的接口,主要是利用了C++运行时绑定的特性.这种方式结合事件机制 是目前我参与的项目中模块之间调用和通信的主要方式.

timoo进行回复 取消回复

邮箱地址不会被公开。 必填项已用*标注