小序
《打开潘多拉的魔盒》——这是一系列文章,这些文章并不是真的要讲述潘多拉 MM 打开魔盒的故事。这些是技术文章,是要通过真实的案例来讲述软件系统的设计过程。本文中所采用的真实案例是网页游戏项目中的抽奖系统,抽奖系统比较独立,且涉及的专业术语比较少,所以易于读者理解。但是,即便这样,这篇文章还是稍微有一定难度的,光是解释游戏划方案可能就得需要很多文字。我假定作为读者的你,至少从事过一到两年的 Web Game 开发,并且对游戏服务器端的架构有一定了解,清楚消息处理层 MsgHandler、业务层 BizService、IO 层以及多线程的基本内容,并且了解 UML 。文章中不会出现太多的具体代码,或许在后面的章节中会展示一些示例代码。我们主要讨论的内容为:软件系统是如何被设计出来的?
我比较喜欢将技术问题还原于生活,这样容易让人理解并作出正确判断。其实技术就是这样,技术源于生活,又比生活抽象……所以,我不太习惯使用一大堆专业术语或者是字母缩写来武装自己。通俗易懂就很好了。这将是一系列介绍方法论的文章。
开始之前
问题怎么解决并不重要,重要的是:问题是什么?
在开始讲述之前,还是先简单了解一下我们将要讨论的目标系统:潘多拉魔盒系统。正是因为这个系统的名字,所以才有了我这篇文章的标题。其实软件设计过程就如同打开潘多拉魔盒一样,充满了很多未知。
潘多拉魔盒系统,通俗一点来说就是一个游戏内的抽奖系统(更通俗一点就是:开宝箱)。但是与一般的抽奖系统不同,该抽奖系统是定时开启的,奖品数量是有限的,而且这个数量还是公共的。举个例子:好比潘多拉魔盒里有 10 个奖品,这 10 个奖品会被所有玩家看到。这时候有一个玩家抽走 1 个奖品,大家会看到魔盒里还剩下 9 个奖品。
如果这 10 个奖品中有 1 个是超级大奖,那会是什么情况呢?也就是对于所有人来说,这个超级大奖出现的几率是 10%。恰好,刚才那个倒霉的家伙抽走了一个不是大奖的奖品,现在大奖的出现几率就增加到 11.11%。如果再来另外一个倒霉的家伙,抽走了另外一个不是大奖的奖品,那么现在,超级大奖的出现几率就增加到 12.5%……
随着时间的推移,所有人都会看到大奖的出现几率越来越大。最终,会有一个人横空出世,为了抢到大奖,一口气抽走所有奖品。这种行为学名叫作“包圆”。
接下来还得详细说说规则。
潘多拉魔盒系统,又可以看作是一种游戏内的活动系统,在同一时间段内能且只能开启一个(这个是游戏策划规定的!)。被开启的这个魔盒活动,还不是随随便便开的,而是先要计算服务器上玩家的平均等级,然后根据这个平均等级所在的等级段,来开启相应的魔盒活动。文字写到这里,怕是要进行不下去了,还是用图形来说明问题吧。请看图 1:
(图1)等级段
图中的三角形即代表等级段
通过图 1,我们可以得知潘多拉魔盒系统存在一个等级段的概念。举个例子,当服务器上玩家的平均等级为 10 级的时候,魔盒系统只能在 0~20 这个等级段中开出奖品。当服务器上玩家的平均等级为 30 级的时候,魔盒系统会进入下一等级段,在 21~40 这个等级段中开出奖品。
上面已经交代了等级段的概念,大概有个印象就可以了。还得继续往下面说。等级段之下就是潘多拉魔盒,魔盒可以有很多个。就像图 2 所示:
(图2)潘多拉魔盒
图中的正方形即代表潘多拉魔盒
等级段之下有潘多拉魔盒,这个我们现在也知道了。而潘多拉魔盒是有开启顺序的,每一轮只能开启一个魔盒!当魔盒 1 中的奖品被抽完之后,才能开启魔盒 2。魔盒 2 中的奖品被抽完后,才能开启魔盒 3。当魔盒 3 中的奖品被抽完之后呢?系统会从魔盒 1、2、3 中随机抽取一个继续下一轮活动。就如图 3 所示:
(图3)第 4 轮抽奖
会从魔盒 1、2、3 中随机选择一个魔盒
图 3 中给出的是第 1 轮到第 4 轮的抽奖示意图。那么第 5 轮呢?第 5 轮抽奖,就和第 4 轮是一样的。也就是说,系统在开始的时候是有顺序的,后来就变成随机的了。一直到全服玩家平均等级达到 21 级或以上时,系统进入下一阶段。而且在下一阶段的时候,系统还是从有序变成无序。每一轮抽奖结束后,系统会休息一小段时间,然后继续开启下一轮。
最后还要说一下。每一个魔盒中会有很多奖品,就如图4所示:
(图4)魔盒中还有奖品
图中的六角星即代表魔盒中的奖品
注意,在图 4 中我借助了 UML 的类图中的聚合连线,来说明一个魔盒中存在多个奖品的事实。UML 可以不仅只是局限于 UML 哦。大致内容我们已经了解了。接下来,让我们进行一次完整的时间旅行吧……
【时间】2012/12/1;
【服务器中玩家平均等级】6 级;
今天,潘多拉魔盒系统开启了魔盒 1,魔盒 1 中有 10 个奖品。
玩家们踊跃的参加了抽奖活动;
【时间】2012/12/2;
【服务器中玩家平均等级】9 级;
今天,潘多拉魔盒系统开启了魔盒 2,魔盒 2 中有 20 个中级奖品。
玩家们又踊跃的参加了抽奖活动;
【时间】2012/12/3;
【服务器中玩家平均等级】13 级;
今天,潘多拉魔盒系统开启了魔盒 3,魔盒 3 中有 30 个高级奖品。
玩家们依然踊跃的参加了抽奖活动;
【时间】2012/12/4;
【服务器中玩家平均等级】17 级;
今天,潘多拉魔盒系统随机开启了一个魔盒,是魔盒 2,魔盒 2 中有 20 个中级奖品。
玩家们依然又踊跃的参加了抽奖活动;
【时间】2012/12/5;
【服务器中玩家平均等级】22 级;
今天,潘多拉魔盒系统进入到第二阶段,并开启了第二阶段的魔盒 1。
该魔盒中有 40 个更高级奖品。
大家更踊跃的参加了抽奖活动;
好了,到目前为止,基本上已经把潘多拉魔盒系统介绍清楚了。前面的文字可能有些枯燥,但我还是会尽量保证简单、轻松的风格。在这之前说的一大堆,都是系统内置的潘多拉魔盒活动,另外,游戏运营也会开启自定义的潘多拉魔盒活动。运营开启的潘多拉魔盒活动和系统自带的潘多拉魔盒活动,并无差异。但是,在运营开启潘多拉魔盒活动时,系统自带的活动必须暂停并需要保存现场。等到运营活动结束后,再恢复现场继续运行。就如同图 5 所示:
(图5)运营魔盒活动
在运营魔盒活动开始前,需要对系统魔盒活动保存现场
这个运营需求确实比较麻烦,说其麻烦,主要是因为需要保存和恢复现场。到现在为止,所有的策划需求和运营需求基本上就都已经交代完了。如果没有看太明白的话,可以回过头去再仔细阅读一遍。其实前面这些文字,有点需求分析过程的意思,在这个过程中我们找到了潘多拉魔盒系统中的几个重要的业务概念。
在开始设计之前,先要说清楚所要解决的问题是什么(What)?这非常非常关键。即,讨论问题时,需要建立一个共同的基础。这也正是我为什么在文章的最开始先介绍整个系统的原因。很多技术设计文档都存在一个致命的缺陷,那就是从开头到结尾都是在强调怎么做(How)?这样是不易阅读的。技术设计文档,其实就是在“讲故事”,既然是讲故事,就应该遵照:是什么(What) --> 为什么(Why) --> 怎么做(How)这样的顺序。当然,也可以是:是什么 --> 怎么做 --> 为什么。不管顺序是怎么样的,在最开始一定会交代问题是什么?而当你在说清楚问题是什么的时候,别人的脑海里就已经呈现出怎么做了。
对于系统中的重要概念,要画图分析。人类的大脑对于文字的接受能力,远远不及图形。能画图时多画图,画图可以开发右脑,对于程序员来说,是个好消息,即锻炼了逻辑思维,又锻炼了想象力。有些问题,是需要想象力才能解决的……程序员的一个关键能力,是将抽象问题具象化,然后再将具象化的问题抽象化。这有点从肯定到否定,然后再到否定之否定的味道。
这篇文章是介绍潘多拉魔盒系统到底是个什么样子,而在介绍的过程中就已经开始进行设计分析了。目前分析的范畴是“业务模型(Business Model ,或称作领域模型 Domain Model)”分析。业务模型分析,会将目标系统切割为“业务对象(Object)”和“业务行为(Action)”。这个可能有点抽象,我打个比方。比方说开发个 ATM 机系统吧,其“业务对象”就是银行卡(Card)、现金(Cash);“业务行为”就是存款(Deposit)、取款(Draw)。
大家还记得这个吗:程序 = 数据结构 + 算法。“数据结构”不就是“业务对象”么?“算法”不就是“业务行为”么?此时此刻,是否有些共鸣呢?
通过本篇文章,我们可以初步得到一个类图,如图 6 所示:
(图6)类图
根据业务模型,得到一个类图
这是我们的第一个设计成果……