作者: coffeewoo 先生
上一篇我们图形化建模的部分基本上完成了,得到了业务用例模型, 这帮助我们获得了功能性需求。得到了业务场景和用例场景,这帮助我们获得了面对业务的执行过程描述和概念(逻辑)模型,让我们知道业务将如何的运作。得到了用例实现以及领域模型,这帮助我们得知哪些业务用例将在系统中实现,对应这些用例,哪些业务实体将会被包括进来,以及它们如何帮助业务实现。上一篇我们也留下了悬念,对于业务执行过程来说,除了以上的成果,我们还需要知道业务规则,以及业务实例的属性。即我们要如何做以及做什么。这一篇就来讨论这些内容。
先说说业务规则。笔者习惯将业务规则分为三种。
一种是全局规则,这种规则一般与所有用例都相关而不是与特定用例相关,例如actor要操作用例必须获得相应的授权,用例的操作与授权级别相关,或者用户在系统中的所有操作都要被记录下来等等。这类规则笔者习惯于,并且也建议将它们写到用例的补充规约里面去,因为它们一般与具体的业务功能性要求没有直接关系。有时候,这类规则也被写到软件架构文档中。关于用例补充规约以后再讨论。
第二种是交互规则。这种规则产生于用例场景当中,例如当提交一份定单时,哪些数据是必须填写的,用户身份是否合法。当然也包括一般理解上的业务流程流转规则等,例如金额大于一万元的定单被定为VIP定单进入特殊流程等。这类规则一般要写到用例规约中。交互规则实际上还有两个是比较特殊的,一个入口条件,也称为前置条件,即actor满足什么条件才能启动用例;另一个是出口条件,也称为后置条件,即用例结束后会产生哪些后果。稍后参看示例。
第三种是内禀规则。所谓内禀规则是指业务实体本身具备的规则,并且不因为外部的交互而变化的规则。例如,每张定单至少要有一件商品,同一类商品数量不能大于5件等。同时也包括大家所熟悉的数据效验规则,例如身份证号必须是15或18位,邮编必须是6位等等。这类规则是业务实体的内在规则,因此应该写到领域模型文档中,稍后参看示例。
读者或许对把规则这么分类有不同的习惯和理解,可能会觉得麻烦。但是笔者这么做有充分的理由。首先,全局规则与具体用例无关,它实际是系统应该具备的特性,这些规则把它分出来目的就是为了让系统去负责这些特性的实现。读者可以结合实际考虑一下,通常授权,事务,备份等特性都是由系统框架去实现的,具体的功能中并不去实现它们。如果读者有过基于某个框架开发应用的经历的话一定会认同笔者的话。其次,交互规则是在用例场景当中产生的,它们规定了满足什么条件后业务将如何反应。通常,这部分规则是最复杂,也最不稳定,最容易变化的。大家所说的需求经常变更相信绝大部分就来自于此。因此将这些规则单独列出来并给予关注和管理是很有必要的。同时这部分规则通常在系统中以Control类去实现,MVC模式如此,SOA架构中的BPEL也是如此。如果需求无可避免的要变更,那么,将交互规则单独提取出来,并设计成为扩展性很强的结构就是一种有效的应对手段。第三,内禀规则与外部交互无关,不论谁,在什么情况下提交定单,必须有至少有一件商品;不论你在哪个国家,在什么公路上开车,刹车都是必不可少的。这种内在的性质让你想到了什么?面向对象的封装原则对吗?这类规则应该实现到你的实体类中去,不论你的业务实体是EntityBean,JavaBean,POJO还是COM+,根据面向对象的封装原则,内禀的逻辑一定不要让它暴露到外部去。
这么分类以后,对软件成熟度比较高的组织来说,提供了很好的Level Reference。如果你是架构师,应该关注的是全局规则;如果你是设计师,应该关注的是交互规则;如果你是程序员,应该关注的是内禀规则。
在这里笔者想说点题外话:)。笔者曾经看过一篇《架构师已死》的文章(很抱歉已经记不起出处和作者,如有冒犯之处请海涵),作者的观点认为架构设计完成后,通常到最后改得面目全非,既然一开始不可能考虑到所有可能,何不如在开发过程中持续总结,重构,最后架构会自然而然出来的,如果这样,架构师有何用处呢?笔者认为这个说法是有一定道理的,不过要看软件组织架构和软件过程的定义,不可一概而论。《架》一文的作者是XP的fans,对XP软件过程来说,本来就不需要架构师这个角色,甚至连设计都不需要,开发,测试,改进,重构...,当然,从一开始就没打算按照一个stable的方法去做,架构师也就没有存在的必要。架构师在XP中已死,不过在RUP中还活着:)。软件界一直对XP和RUP有着争论,笔者无意在本文中界入这个争执,只是话已经到此,就顺便表达一下笔者观点。XP和RUP都是非常优秀的软件方法,只是它们各有各的适应范围。对于中小型公司和中小型软件来说,XP是非常有效的管理方法,它能大大降低管理、开发成本和技术风险。不过要是对于大公司和大型项目来说,XP就不适用了,这时RUP却非常适合。你能想象洛克希德·马丁公司用XP的方法来开发F-35战斗机会是一个什么情形吗?没有人清楚的知道将来的飞机整体是什么样,反正先造一架出来,摔了找找原因,改进改进,重构一下,再造一架....再摔了,没关系,咱们拥抱变更,再造就是了。呵呵,那XP什么情况下适用呢?如果你是一个杂货店的老板,不知道什么样的商品受欢迎,没关系,先各进一小批货,卖上一段时间,受欢迎的货品多进,不受欢迎的不进,跟顾客多交流,顾客喜欢什么商品咱就进什么,不断改进,最后一定会顾客盈门的。这时如果这个老板先做商业分析,客户关系分析,消费曲线分析....还没开业呢,估计就破产了。另外,RUP和XP也不是非此即彼的关系,在造F-35的过程中,对整体飞机来说,用RUP是适合的,具体到发动机的提供商,倒是大可XP一把,最终只要提供合格的发动机就OK了。
题外话说了不少,书归正传。业务规则分类以后,就应该按分类去调研了。
全局规则很难从用户处调研得来,通常这方面是用户的盲点。这主要是由有经验的系统分析员,或架构师以及客户方的IT部门(如果有的话),从业务特点、应用环境、行业规定、法律规章等等方面去总结,再求得客户方的认可。
交互规则从用例场景而来,每一个场景,场景中每一个交互的过程可能都隐含着规则。这就需要与客户多讨论。请参考本系列文章的第3篇关于涉众的讨论,交互规则最主要的来源是业务提出者和业务管理者,最好不要去找业务执行者。
内禀规则是针对业务实体的,因此要对每个业务实体的属性进行罗列,并找出它们的规则。内禀规则最主要的来源是业务执行者,需求人员应该更多的去与他们交流。
现在来谈谈业务实体的属性。业务实体的属性在这个阶段应该用业务术语来描述,而非计算机术语。调研范围是上一篇模型中得到的领域模型中的每一个实体,而属性的原始来源是客户的各类实际表单,以及在交流过程中客户提出的各种要求。如果业务实体有状态,并且是比较复杂的,那么在建模的时候应该有一个状态图来说明。请参看本系统文章提供的建模实例中'图书'业务实体下面的状态图。请读者注意,在本文后面提供的例子中,业务实体描述看上去象是一张数据表,但它绝对不是数据表。它是对业务中实体属性的业务角度描述。系统分析不是做设计,脑子里不要有任何关于设计或实现方法的想法,这些想法会误导你做出不适合的决定。你的职责是通过一个合理的模型完整的将业务描述出来,并求得客户方的认可。任何替客户和架构师,设计师甚至程序员“着想”的方法其实都是不恰当的。
最后本文提供一个用例规约的例子,每个用例都应该写一份用例规约。本文提供的这个例子基本上来自RUP提供的模板,不过在实际工作中笔者做了些修改,供读者参考。这个例子的蓝本还是本系统文章一直在使用的网上图书馆的实例。点这里下载用例规约例子,点这里下载建模实例。
到这里,需求过程差不多也该结束了。但是我们的确还有一些工作要做。如果读者所工作的组织是用RUP来做需求的,而客户方或者监理方未必会对这种需求文档表示满意。他们会以国标来要求你。同时,到目前为止,我们产生的成果都是一些分离的图形和文档,对于客户来说,这的确是不好的文档结构。难道客户的采购清单里还需要包括Rational Rose,这样才能阅读你提供的需求文档吗?显然这是不可能的,所以,给用户提供的文档还是以传统的《需求规格说明书》为好。下一篇就讨论一下如何将我们的分析成本集成到《需求规格说明书》中。顺带讨论一下用例补充规约和系统原型的产生以及它的作用。敬请期待。