工程结构的层次图和基本职责
个人还是偏爱在设计初第一步使用模块层次图来描述一个工程的基本结构。因为层次图可以在较浅的层面上对整个工程进行全面考虑,比较容易在一开始就确定细化设计的重点,并且通常层次图也可以对整体工程的子工程划分起到启发作用。但模块层次图无法具体体现出单层中各个模块之间的交互和依赖关系,也不能提供程序代码的层次划分关系,不能单独使用层次图对开发进行指导。
工程层次结构如图
图中的分割线表示多平台支持的分界线,通常分割线所在层次越高,开发难度就越高,分割线可以选择在网络协议层之上,或者在业务逻辑层之上不再支持跨平台实现。
具体情况要根据需要多平台支持何种业务来定。例如客户端在Windows平台上,服务器在Linux平台上,可以选择业务逻辑层之上不再支持
多平台实现,如果客户端在Windows平台上,逻辑服务器在Windows平台上,后端服务器在Linux平台上,也可以选择在网络协议层之上就不再支持
多平台实现。
跨平台支持层:提供跨平台的类型定义和函数定义,例如对int64,int32等的定义,以及对sprintf等函数的定义。
需要注意的是,由于该层存在的主要目的是使上层开发中,无需关心所面向的平台,因此在其之上的
各层开发中,需要调用某些平台的特有API时,应该将该API定义在《跨平台支持层》中,并且对该API
提供其他平台实现方案。该法则要保持到上图的分割线处。
实用工具层:提供内存监管,日志,时钟,Profile等,无需在这层提供多线程工具等平台差异较大的功能。
网络协议层:提供所有网络协议的定义,压缩,存储,生成,解析等功能
业务逻辑层:提供所有业务逻辑,并提供对网络协议的存取接口。
PS:其实网络协议层和业务逻辑层之间的关系比较难以确定。首先网络协议层在定义协议时是否需要使用到逻辑层中的各种定义和枚举。如果是,则协议层依赖于逻辑层。其次是逻辑层是否应该定义如何存取协议的接口,如果是,逻辑层依赖于协议层。而在部分项目中,逻辑层本身不是跨平台的,如果协议层依赖于逻辑层,则协议层本身无法跨平台。最后我选择了以下方式:协议层在下,逻辑层在上。协议层中不要出现任何逻辑层中的定义和枚举,应该保持其自身的独立性。在协议定义时,可以选择使用int替代枚举,选择比逻辑层长的,通用的字符串长度替代逻辑层中的某种字符串长度。协议层本身应该只关注如何进行内存转储并在网络上传输,无需关心其内容的实际含义,也不需要对其内容的逻辑合法性进行检查。
引擎层:该层提供渲染,音效,网络等具体功能的封装和实现。无需考虑跨平台需求,只需对每种平台实际需要用到的功能单独提供模块即可。
应用层:该层实现客户端,服务器,编辑器和其他工具,无需考虑跨平台。但应该尽可能考虑在不同应用程序中,复用下层模块。