8.2.3 提炼类和属性
8.2.3.1 提炼的来源
(1)从需求规约之外的其他素材提炼
建模类及类之间的关系,可能在软件开发的分析工作流之前就已经发生了。
第7章“需求启发”中就提到,我们在研究资料的时候,可以通过画类图来整理领域的概念。整理领域概念时,有时还可以加上状态机图(但不会使用序列图,自行思考一下为什么)。即使不是为了开发软件,也可以通过这些手段来整理领域知识,帮助我们更快掌握。
拿一篇上过春晚的经典科学论文《母猪的产后护理》为例,如图8-46。
图8-46 《母猪的产后护理》
通过类图整理图8-46的素材,如图8-47。
图8-47 用类图整理《母猪的产后护理》领域知识
图8-47可以称为“母猪的产后护理的领域模型”。这个模型可能和信息系统没有关系,因此不能称为“母猪的产后护理的核心域模型”或“母猪的产后护理的分析模型”。
如果某个信息系统“母猪产护宝”要封装图8-47的领域知识,那么图8-47可以称为“母猪产护宝的核心域模型”或“母猪产护宝的分析模型”,但不适合称为“母猪产护宝的领域模型”,因为“母猪产护宝”中封装了核心域和非核心域的知识。
从上面例子可以看出来,对于以上提到的几个用语,本书是按以下定义使用的:
领域模型:描述某个领域中的概念及概念之间关系的模型。
分析模型:从核心域视角描述的信息系统的模型。
核心域模型:等同于分析模型。
它们之间的关系如图8-48。
图8-48 领域模型和分析模型
模型可以用各种表示形式来表示,相应的形式可以叫“领域类图”、“领域ER图”、“分析类图”、“分析状态机图”、“分析类文档”、“分析状态机文档”……。
我们可以从各种素材中提炼某个领域的类和属性,不过这些类只能叫领域类,不一定是合适的分析类。到底哪些领域类会成为目标系统的分析类,需要从目标系统的需求模型(如果用本书上册的方法表示,就是系统用例规约)来判断该系统是否需要这个类。
没有需求规约,目标系统的边界以及应该承担的责任没有理清楚,那么,提炼得到的类到底是不是目标系统将来需要维护的概念,是没法判断的。也就是说,虽然在很多时间点、从很多素材都可以提炼类,让我们在确定分析类时,省去了许多思考,但分析模型的最终依据只能是需求模型。
当然,如果你脑子里对于系统该干什么不该干什么清清楚楚,只不过没写出来,那也算是有需求模型了——不过你得确定你真的懂,而不是拿这个当遮羞布。
如果按照本书所采用的面向对象建模、UML表示法和IvarJacoson三种类的分割,某个领域模型可能会包含某个系统的分析模型中的实体类部分,但不会包含边界类和控制类部分。
有些书籍和文章作者,对软件开发的工作流没有清晰的概念,把所有用“业务语言”表达的模型,包括组织流程,系统需求规约等,通通叫作“领域模型”。这是不正确的,我们在阅读时要注意分辨。
(2)从需求规约提炼
这是提炼类最严格的依据了。
阅读用例规约的基本路径、扩展路径、字段列表和业务规则部分(即所谓“功能需求”部分),针对表示名词或事件的词汇,逐个思考,这是不是系统要记住的核心域概念?如果是,那么它是类,还是某个类的属性?如图8-49。
图8-49 从用例规约识别类和属性
关于“系统要记住的”概念,可以这样思考,系统需要懂得哪些信息,才能根据执行者的请求提供恰当的价值?
如果您有关系数据库建模的经验,也可以这样简单地思考:如果系统需要维护的信息都采用关系数据库来保存,那么数据库里应该会有哪些表?这样思考得到的表和实体类基本上是一一映射的。表对应类,列对应属性,行对应对象,关系对应关联。后面我们会讲到,类模型可以直接转换成关系数据库模型,不需要再花工作量做一遍关系数据库建模。
如果关系数据库建模技能掌握得好,得到的数据模型符合1NF、2NF和3NF,那么用关系数据库建模的思考方式得到的类图极有可能也是合格的。反过来,也有理由怀疑,自诩关系数据库建模能力强的人,如果类建模做得乱七八糟,估计也有吹牛的成分。
当然,我们画类图的目的不仅是为了得到关系数据库,面向对象和关系数据库(或任何的具体存储方式)也没有必然的绑定关系。任何系统都可以用面向对象的方式来构造,不管它用什么方式来存储对象。
以电梯为例。我们把为乘客提供电梯服务所需要的所有软硬部件看作一个整体,称为“电梯系统”。乘客在发出某次召唤之前,电梯系统要懂得各部电梯当前运行方向、当前所处楼层、待去往的目标楼层集合以及楼层的结构,才能够合理应对乘客的召唤。这些可以看作系统要记住的信息。乘客姓名、乘客召唤电梯的时间、电梯曾经去过的楼层等,系统不需要知道。画出类图如图8-50。
图8-50 电梯系统可能需要的实体类
这些信息不一定需要被“持久存储”。图8-50中的概念中,当前楼层、目标楼层、方向的信息一直在不断变化,甚至在电梯系统停止服务时会被清空,但不影响图8-50的类结构。