simonw代码@痕记

导航

N-Layer, COP, SOA In WOW Addon Develop

术语解释
N-Layer, N层设计开发模式.
COP, Component Oriented Programming, 面向组件的编程.
SOA, Service Oriented Architecture, 面向服务的架构.
WOW, World Of Warcraft, 暴雪公司推出的一款著名网络游戏, 魔兽世界.


前言

    软件开发从第一台计算机诞生之日起至今已经经历了50多年的发展, 复用一直以来是众多开发者所追求的理想, 而复用本身也经历了若干阶段的变, 从最简单的API, 到类库, 到今天的框架, 组件, 服务等, 随着复用层次越来越高, 开发一个应用也变得越来越容易, 这充分说明了, 站在巨人的肩膀上可以尿的更远.

    暴雪魔兽世界是一款具有划时代意义的网络游戏, 他引入了很多颠覆传统的概念, 当然篇文章所描述的是关于开发方面的内容, 所以其游戏性创新暂且放置. 那么是什么让开发者非常青睐于这个游戏, 就是他开放式的插件运行引擎, 说到插件引擎不能说暴雪是个创新, 在以前也有不少游戏尝试过这样的方式, 但这回暴雪辅助他强大的游戏性和功能将插件引擎发展到了前所未有的高度, 大量的开发者加入了WOW插件的开发行列, 既然是开发, 将永远离不开复用这个概念.

    对于以下概念的阐述, 其特性将紧密围绕WOW插件开发, 于之无关的并不多涉及. 所举示例, 代码仅供说明思路, 并不代表实际如此.


概念

N-Layer (N层)
    将软件按照垂直的职能分为N个层次的设计开发模式. 他要求上层依赖下层提供的服务, 而下层不依赖上层. 在这里这个N指3, 也就是3层架构, UI层, 业务层, 数据层, 更多的分层并不使用于WOW插件的设计开发.

面向组件
    所谓组件, 指实现了一定功能并且在逻辑及物理独立的软件实体, 他由一个类或若干个类组成并对外暴露他的服务接口, 依赖这些接口实现与外界的通讯. 例如一个Email处理组件是一个单独的dll文件, 外界调用他只需要关心他的服务接口像发信, 收信一类的而不需要关心他的内部实现. 

    面向组件是一种比面向对象更高级的软件复用形式, 他的思想是用组件搭配来组合成一个完整应用体系. 例如我们使用Email组件, 工作流组件, 内容发布组件来组成一个简单的办公自动化系统.

面向服务
    面向服务更是将面向组件的思路发扬光大, 标准化了组件间的通讯协议, 更有利于异构以及分布式应用. 当然在WOW插件开发中我们用不到分布式.


需求与优势

N层设计的好处
    采用N层设计的系统, 扩展性非常好, 由于依赖关系只是单方向的, 抽换上层, 将不会对底层产生影响. 例如一个办公自动化系统, 在以前我们把他做成了CS(客户端-服务器)模式, 为适应因特网的发展, 需要一套BS(浏览器-服务器)的系统, 采用N层设计的话, 你只需要为系统更换不同的UI, 即可完成这个任务而不是推倒重来重新写一个适合BS的系统.

面向组件与面向服务的优势
    面向组件与面向服务的优点就是通过粗粒度的接口及标准的通讯协进行复用, 我们通常用面向对象的思路来设计框架, 类库等, 通过暴露的接口来实现复用, 这是一种细粒度的接口, 可复用性非常好, 他代表着通用性, 但同时也代表着你需要做大量的自定义工作. 而组件的粗粒度接口专业化的服务, 通用性显然不如类库级的细粒度接口, 而一但适合应用我们基本上只需要配置下就一切搞定. 软件发展到今天, 各行各业的专业化服务需求随着IT应用的成熟越来越趋于标准化, 因此组件有了大展身手的空间 - 即粗粒度接口提供专业化服务成为一种节约成本实施快捷的流行解决方案.

WOW插件的运行环境
    WOW插件是运行在以游戏平台为宿主的Lua语言运行时下, Lua是一种动态语言, 结构异常灵活, 与其他动态语言不同的是小巧灵活没有多余的库, 整个解释器只有不到200k. 因此非常编写适合游戏环境的上层应用. 而WOW为了安全起见, 封闭了很多Lua的功能, 如IO读写, 多线程等. 所以这里的Lua功能十分有限, 除了一些功能性的系统库, 如Math, String等, 就是游戏本身定义的内部对象.

WOW插件现状
    在需求方面, 随着游戏的时间推移, 玩家的需求越来越固定, 也越来越标准. 以Decursive插件(一键驱散)为例, 不像从前, 只有高手才在用, 如今相信没有哪个玩家不知道或不用的了, 也就是说驱散这个需求已经很确定了. 

    在插件开发方面有两个问题, 第一当一个插件开发出来之后无论作者怎么努力却总也无法满足所有玩家的需求, 不同玩家的需求经常是矛盾的, 第二对于开发者, 明明另外一个插件有我需要的部分功能我却没法直接拿来用, 因为他和他的界面存储已经绑定到一起了, 我想用的话除非仿照他的思路重写.

    在这样的现状下, 我们怎样才能做的更好呢? 刚说了半天上面的概念到底和WOW插件开发有啥关系呢, 一个游戏的插件开发也能用到如此流行的思路么? 是的, 伟人说过, 人有多大胆, 地有多大产. 不怕不敢做就怕不敢想, 因此就产生了我大胆的设想. 


插件开发架构

N层式的设计



    这是一个纵向的方式, 其设计为我们带来了软件本身需求变更解决的灵活方案, 例如, 用户对我的插件提出了多种不同的界面要求, 我无法一一满足, ok, 我可以设计出多个界面的版本让用户选择, 而我的功能和数据方面都无需改动, 用户可以在不了解你的功能算法的情况下根据你功能模块的接口来自己定制符合自己个性的界面.  再举个例子, 有的用户喜欢用SavedVariables来存储设定, 这样方便, 有的用户希望使用Config文件来存储自己的配置, 这样保存时间长便于移动, 而你可以提供2种方案的数据层来满足这样的需求.

    采用3层模式开发插件应该是一个合格开发者的基本功, 很多优秀插件的核心思路都是这样, 总结一句话, 这样的模式设计不至于让你在一个普通的需求变更的情况下手足无措, 进而从头到尾修改你的代码. 更多的代码行为可以参考我的插件ShortKeyShortRobot的设计, 虽然没有使用面向对象, 但层次清晰体现其中. 如若定义出标准可以很方便的拆为组件.

面向组件, 服务的设计
    这是一个横向的方式, 其设计是为了更大规模的复用, 目的不仅用于一个插件中, 而是可以复用于多个插件中. 组件方式的设计主要针对业务模块, 也就是功能模块, 当然他是在只有需求相对固定的环境下才能发挥威力. 核心设计便是接口与接口间通讯的数据结构的确定, 这就是标准, 有了标准我们才能更好的实施这个方案. 现在假定有一个大家认可的标准指定委员会. 

    依然拿Decursive举例, 因为这个需求已经很大众化了, 委员会需要对他定制标准才好使得日后依照标准开发出的插件具有很强的复用性, 分析他的主要功能有两部分, 驱散和优先列表. 如下列代码所示, 分别定义了驱散与优先列表的对外服务接口, 以及接口间的通讯标准参数person(指被驱散的人). 需要注意的是通讯标准也需要定义清晰, person代表被驱散的人, 那么这个人是一个玩家的名字还是一个Unit编号(如, Partymember1, RaidMember23, target等), 如果没有明确的定义别人将无法正确使用, 因此我在这里定义person代表一个unit编号. 他们的实现细节不是委员会的事情.
 
Decursive = {};
--person : Define by Unit
function Decursive:Dispel(person)
    
--do Dispel for the person
end

PRIList 
= {};
--return a person
function PRIList:GetTopPerson()
    
--get the person whose PRI is the highest
end

    ok, 标准定义好了, 可以提交给插件作者, 不同的插件作者按照他们自己的喜好或思路实现了不同的驱散和优先列表功能. 例如在实现优先列表的时候, 有的作者喜欢先判断距离再查看debuff, 有的作者喜欢先查看debuff再查看距离, 有的作者喜欢简洁的判断只筛选小组内的玩家, 有的作者喜欢功能强大的判断所有友方玩家. 这样做各有个的好处, 各有个的适用范围. 玩家们就可以依据自己的喜好选择不同的优先列表组件来满足自己个性的需求. 而优先列表的组件不仅仅只适合Decursive这类的插件, 其他类型的插件只要觉得他提供的服务恰当依然可以使用, 举例, 我开发了一个确定首要保护目标的插件, 我发现某个优先级列表组件非常适合我的使用, 因此我直接拿来就用了, 免去了再开发.

    类似于Decursive这样固定的需求, 游戏中不在少数, 如果对这些需求能确立相应的标准, 依靠广大开发者建立起一个完整的组件库, 那么按需所求的插件将不再是个梦想, 普通玩家制作自己个性化的插件也不是遥不可及的目标, 到时候只需要下载相应的组件组合便成为自己的所需的插件.

面向组件的延伸
    面向控件, gzkuru在Mop上发了这样一个帖子很不错, 通过封装界面和简单的业务而成, 这也是面向组件的一个缩小化的体现. 其实对于N层设计的每一个层次或者某几个层次的组合都可做为组件开发, 而唯一的判别方式就是看你的组件是否对应着一种流行的需求. 当然标准依然是必不可少的.



最后

    本文仅代表个人观点, 另外也欢迎各种相同或不同的意见与想法共同参与探讨. 组件化的道路仍然是个未知数, 我也在不断的探索中, 毕竟与其他开发技术不同的是插件开发所受限制极大. 我希望有一天能看到各种组件百花齐放的局面, 使用者只需找到自己喜欢的积木就能搭建自己的理想的城堡.

    另外想指出一些开发者们的误区, 一些观点认为 WOW插件规模很小不需要设计, 其实规模小不是理由, 设计与其说是一种功夫不如说是一种责任, 插件都是开源的, 你不会保证没有人在用在看你的东西, 好的设计无论在阅读或在使用过程中都是赏心悦目的. 另一些观点认为, 不需要使用任何人的库, 自己的能力很强所有东西都自己写. 现在已经不是程序员是英雄的年代, 善于利用别人的经验你会得到更大的成果, 还是那句话, 站在巨人的肩膀上可以尿的更远.


Simonw 2006.10.15 / Msn: i-simon@msn.com
如有转载请注明出自博客园及原文地址:http://simonw.cnblogs.com/
欢迎各位开发者能团结起来加入CWOW Developer Group

posted on 2006-10-15 03:52  simonw  阅读(1393)  评论(1编辑  收藏  举报