《大象:thinking in uml 》(第二版) 11章 系统分析 1-2节 确定系统用例、分析业务规则

只供参考,喜欢请支持正版图书

11.1 确定系统用例

《大象:thinking in uml 》(第二版) 11章 系统分析 1-2节 确定系统用例、分析业务规则_第1张图片具体说来,这些方法包括:
■ 映射
映射是最简单最直接的方法,例如值机人员办理登机手续这个备选用例就可以不加修饰地直接被采纳为系统用例。

■ 抽象
抽象也是比较常用的方法,当业务场景当中的备选用例不能够被直接映射时,我们可能需要进行一些抽象,找到该备选用例在计算机当中真正要做的事

11.1.2 现在行动:确定系统用例

《大象:thinking in uml 》(第二版) 11章 系统分析 1-2节 确定系统用例、分析业务规则_第2张图片《大象:thinking in uml 》(第二版) 11章 系统分析 1-2节 确定系统用例、分析业务规则_第3张图片图11.3 申请永久用电系统用例

11.1.3 现在行动:描述系统用例

■ 用例场景示例
我们先来看一个用例场景的例子,从图11.3所示的用例列表中选取申请登记作为示例。在获取系统用例时我们得知,申请登记是业务员创建申请单、录入用户资料的过程。现在,我们要做的是描述业务员如何操作计算机来完成这个过程。我们首先选择活动图来描述操作过程,其结果如图11.4所示
《大象:thinking in uml 》(第二版) 11章 系统分析 1-2节 确定系统用例、分析业务规则_第4张图片

■ 用例规约示例

表11-1 用例规约示例
《大象:thinking in uml 》(第二版) 11章 系统分析 1-2节 确定系统用例、分析业务规则_第5张图片《大象:thinking in uml 》(第二版) 11章 系统分析 1-2节 确定系统用例、分析业务规则_第6张图片

11.2 分析业务规则

相信有不少读者在自己的项目中也遇到过同样的麻烦。由于业务规则被当作程序的控制逻辑,一旦业务规则发生变化就意味着程序的控制逻辑要相应地修改。暂且不说这种修改是多么费时费力,程序控制逻辑的修改还常常导致系统出现大量的不可预知性错误。即使程序修改是可以接受的,由于业务规则分析并没有作为需求分析过程当中的一项重要工作,而仅仅作为编程人员编写程序的依据,导致的结果是业务规则散落在程序的各个角落。当某个业务规则发生变化时,再没人能够说清楚哪些程序受到了影响。对于程序维护者来说更是恶梦,当客户要求变更业务规则或者出现了计算结果异常时,程序维护者不得不翻遍代码来寻找业务规则的蛛丝马迹

其实业务规则并非近年来的新概念,从20世纪80年代起,就开始了对业务规则的专门研究,还产生了一门新兴的技术BRM(Business Rules Management),以及专门处理业务规则的产品——业务规则引擎。这些技术和产品的目标是将业务规则从程序逻辑当中剥离出来,通过业务规则管理工具将其纳入业务规则库。应用程序处理过程当中需要用到业务规则时则通过业务规则引擎解释业务规则并返回所需的结果。业务规则通常以决策表、决策树、规则语言和脚本的形式来维护

业务规则管理在近年应用越来越广泛,例如在IBM的SOA产品当中就包含有专门进行业务规则管理的模块。再比如现在十分流行的AOP模式及相关产品也致力于将规则从业务逻辑中剥离开来

11.2.2 现在行动:分析业务规则

在9.6提炼业务规则一节中曾经提到过作者在实践中习惯将业务规则分类为全局规则、交互规则和内禀规则三类,并且将全局规则交由架构师处理,交互规则交由设计师处理,内禀规则交由程序员处理。在分析业务规则时,也是按照这三个类别分别进行的

11.2.2.1 分析全局规则

全局规则是指对于系统大部分业务或系统设计都起约束作用的那些规则。相对用例来说,全局规则是跨用例的规则

显然,这条业务规则将对程序产生很大的影响。在程序处理上,由于种种原因所填表单会经过多次修改,而每一次修改都要求在数据库中保存当时的副本。这就产生了历史数据保存问题和历史数据版本管理问题。如果我们将这条业务规则交由程序员去处理,那么在程序的许多地方都需要为此编程。且不论程序员要因此增加多少工作量,同样的历史数据版本管理在不同程序员手里实现的质量肯定是参差不齐的,软件产品质量也就值得怀疑。好的做法是将这条全局规则交由架构师处理,由架构师在软件架构的层次上解决历史数据版本管理问题。

这里举一个简单的解决方案作为示例。架构师在架构中设计了历史数据版本管理框架,通过一组接口提供对这些历史数据的写入和查询。同时规定了业务实体类必须实现的接口和继承的超类,历史数据的写入和查询由历史数据版本管理框架来实现,程序员在编写程序过程中可不必关注历史数据版本管理是如何实现的。图11.6展示了该解决方案的静态类结构;图11.7和图11.8展示了该解决方案的实现时序图
《大象:thinking in uml 》(第二版) 11章 系统分析 1-2节 确定系统用例、分析业务规则_第7张图片《大象:thinking in uml 》(第二版) 11章 系统分析 1-2节 确定系统用例、分析业务规则_第8张图片

11.2.2.2 分析交互规则

一般而言,交互规则可以在业务用例场景、业务用例规约、系统用例场景、系统用例规约当中找到。例如,在图11.2低压用电申请业务用例场景中可以找到两条业务规则:
■ 是否符合用电条件?符合则继续办理流程,否则终止流程办理。
■ 用电审批和配电审批是否都同意供电?是则继续办理,否则终止流程

第二条业务规则是非常简单的决策表例子,并且规则很稳定,不会轻易变化,即使将这条规则实现在程序逻辑里也不会有大问题,因此设计师可以考虑由程序逻辑来处理。但是有些业务规则比较复杂,由程序逻辑来处理就不适合了。例如图11.4申请登记用例场景当中可以找到这样一条业务规则:根据用户名从欠费历史中查询该户名有无欠费记录,若有记录,由人工判断该用户名欠费是否属实。若属实应停止申请。这条业务规则就很不适合放在程序逻辑当中去处理

请读者回想一下你曾经做过的项目,是否经常有这样的情况:A模块的某个业务规则需要B模块产生的数据,则编写A模块的程序员就直接从B模块的数据库表里取数据。这就导致A、B两个模块的程序逻辑混合,B的修改很可能导致A的失败。之所以有的应用系统可维护性差,常常改一个地方导致多处出错,原因就在于各个用例(模块)之间逻辑混合。整个应用系统逻辑就像蜘蛛网一样纠缠不清,当然难于维护。

正是由于交互规则产生于用例场景当中,很可能是跨用例的,它们不但可能由不同的开发人员来开发,还可能分属于不同的子系统、不同的程序包等。因此需要由设计师来通盘考虑,避免不必要的依赖。正如这个例子,申请登记和欠费统计是两个相隔很远的用例,完全没必要因为一条业务规则而在它们之间产生依赖关系而增加应用程序的不稳定性。

为了避免依赖的出现,设计师应当将这条业务规则设计成单独的对象或模块。下面举一个简单的例子。例如设计师设计一个专门用于查询欠费的类来处理这条规则,其类图如图11.9所示,其使用方法如图11.10所示

《大象:thinking in uml 》(第二版) 11章 系统分析 1-2节 确定系统用例、分析业务规则_第9张图片《大象:thinking in uml 》(第二版) 11章 系统分析 1-2节 确定系统用例、分析业务规则_第10张图片如图11.10所示,当申请登记程序需要应用到业务规则时,它首先访问欠费查询规则类,由欠费查询规则类负责向欠费统计用例接口获取欠费记录,进行处理后返回判断结果。这样就解决了依赖问题,两个用例可独立编程,它们之间的交互问题可交给欠费查询规则类来处理

实际上,在应用程序中,类似这样的交互业务规则是很多的,设计师完全可以设计一个业务规则库来管理和解决所有的交互业务规则。下面举一个使用了工厂模式的非常简单的规则管理库设计。图11.11展示了静态类结构,图11.12展示了实现过程。

《大象:thinking in uml 》(第二版) 11章 系统分析 1-2节 确定系统用例、分析业务规则_第11张图片《大象:thinking in uml 》(第二版) 11章 系统分析 1-2节 确定系统用例、分析业务规则_第12张图片

11.2.2.3 分析内禀规则

内禀规则是指那些业务对象本身具备的,并且不因为外部的交互而变化的规则。

例如,在表11-1用例规约示例中可以找到这样一条内禀的业务规则,当填写申请单时,用户名、身份证号、地址、用电类别等为必填项。类似这样的业务规则与其他用例无关,也不会因为跟不同的对象交互而变化。它的内禀性质非常类似于对象的封装原则,因此应当在申请单这个业务对象内部来实现。或者可以在申请登记这段程序逻辑中来实现

不过,虽然内禀规则影响有限,但是将业务规则逻辑混合在业务逻辑当中仍然是不好的编程风格。即使是编码,也需要时时保持代码段的职责单一特性。简单来说,就是一个方法或一个代码片段只做一件事情。职责越简单的代码可读性越好,自然也最容易维护。作者仍然建议程序员们在编写内禀规则时不要将规则逻辑代码混在业务处理代码中,可以将内禀规则代码单独写成一个方法,也可以单独写成一个类,养成好的编程习惯

只供参考,喜欢请支持正版图书

你可能感兴趣的:(读书笔记)