查看原文
其他

《软件方法(下)》第8章2023版连载(04)面向对象的假设

潘加宇 UMLChina 2024-03-10
DDD领域驱动设计批评文集
做强化自测题获得“软件方法建模师”称号
《软件方法》各章合集

8.2 建模步骤C-1 识别类和属性

8.2.1 面向对象的假设

注意标题中提到的"假设"二字。面向对象就是一种假设,如果不认可“面向对象”的假设,也可以分析系统的核心域知识,只不过用的方法不叫“面向对象方法”,叫“面向过程”、“面向组件”、“面向肥皂”、“面向武德”都行,看你的假设是什么了。

面向对象的思考方式比目前的其他思考方式要好一点,原因不是计算机喜欢面向对象或者面向对象更接近于计算机的底层,而是面向对象的思考方式更能帮助人脑去剖析复杂问题。如果计算机有感情,估计它应该更"喜欢"人类用机器语言直接给它发指令,因为这样自己就不用受累搞什么编译、链接。

正如前文提到的,三角函数更能解决复杂问题,不意味着它比全等三角形、相似三角形更容易掌握。面向对象更能帮助剖析复杂问题,不意味着面向对象的思考方式比其他的思考方式更容易掌握,而且随着你掌握了更强有力的思考工具,更复杂的问题就会扑面而来。这些问题早已存在,只不过之前你没有能力来发现和对付它们——“古人很少死于癌症”。

当使用面向对象的方法来分析系统时,我们引入的第一个假设是:

系统由"对象"这样一种东西构成,对象封装了数据和行为。

严格来说,我们建模的是类(也许叫“基于类的方法”更合适),即对象的“模板”,而不是对象。对象是运行时(或模拟运行时)才产生的。

我们通过抽象思维把具有共同特征的对象集合归纳为"类",对象看作类的实例。归类是人类认知的一种基本技能,其哲学讨论可以追溯到柏拉图的理型论(Theory of Forms)。

我们引入的第二个假设是:

对象在一个"对象空间"中运行,在这个空间中发生的所有事情消耗的时间为零。

图8-18 想象的"对象空间"

您可以认为这个"对象空间"存在于大脑中,也可以把"对象空间"想象成一台存储空间无限大,通信和运算速度无限快且分布在全宇宙的超级计算机。在这个假设下,不用考虑什么硬盘、内存、Cache、加载,只需要聚焦于思考核心域知识。

当然,“时间为零”、“无限快”是不可能的。我们的宇宙,目前因果关系的最快速度是光速。

当前现实中的计算机和网络,要发生一段因果关系,例如,从提交关键词到返回查询结果,时间估计会以秒来计,不过,作为人类的涉众可能对此已经表示满意了。

如果当前的计算机和网络资源能够满足人们对性能的要求,那么设计模型(代码、存储……)和分析模型之间映射会非常直接。

反之,如果出现不可调和的性能问题,设计模型可能会有所调整,例如,添加一些冗余,但这样的调整和具体的核心域知识无关,可以把它们归纳成一些套路,出现相应问题时按照套路调整即可,不需要在分析时考虑这些问题。

“不考虑性能”这一点,可以用来判断你思考的问题是分析问题还是设计问题。

我们可以针对分析模型里的元素,一个一个问,“如果没有它,会怎么样”,如果回答是“会有性能问题”,那么,可以从分析模型中把它删掉。

例如,类图中有一个冗余的类,问“如果没有它,会怎么样”,答“查询可能会慢”——可以删掉。状态机图里有一个状态“Transient”,问“如果没有它,会怎么样”,答“会漏掉某些数据没有持久化”——可以删掉。

但如果回答是“没有它,系统就没法履行自己的责任了,因为要做的系统就是一个持久化框架”,那就不一样了。

分析模型受到设计的污染,很容易导致批量的废话刷工作量,导致没有时间思考应该重点思考的核心域逻辑。当然,正如前文所说,这也可能正是某些人故意寻找的遮羞布。

8.2.2 三种分析类

8.2.2.1 Ivar Jacoson的假设

我们引入的第三个假设是:

系统中存在三种分析类:边界类(Boundary Class)、控制类(Control Class)和实体类(Entity Class)。

这个假设借用了Ivar Jacoson在“Object-Oriented Software Engineering: A Use Case Driven Approach”(Jacobson 1992)中的思想。

在UML模型中,我们可以用Ivar Jacoson建议的构造型(Stereotype)来表示三种分析类,如图8-19。

图8-19 三种分析类的构造型

一些UML工具(如Enterprise Architect、Visual Paradigm)已经内置了这些分析类构造型。如果使用的建模工具没有内置这些构造型,可以自己添加如“<<边界>>”等文字构造型;或者不用构造型区分,通过给类起名"某某接口","某某控制",也有助于了解该类在系统中扮演的角色。这一点,和第3章讲到业务工人、业务实体时的做法是一样的。

在设计工作流,三种分析类可以映射到任何实现架构,包括但不限于MVC、MVP、MVVM、六边形、洋葱型……甚至映射到不做任何分割的“架构”。

图8-20列出了三种分析类的责任、和需求的关系以及命名。 

图8-20 分析类的责任、和需求的关系以及命名

图8-21用序列图展示了三种分析类之间的协作。

图8-21 三种分析类在系统中的协作

执行者先把消息发给边界类对象。边界类对象履行它有能力履行的责任,然后把它没有能力履行的责任委托给控制类对象。控制类对象就像总裁办,不做具体工作,只是将责任分解后分配给实体类对象。

分配给实体类对象时,如果某个对象被其他对象组合,应该先分配给组合它的对象,再由该对象分配给它。DDD话语体系中的“聚合(Aggregate)”和这一点类似,本书在后文讲述类关系的章节中会进一步阐述其中差别以及“聚合(Aggregate)”的伪创新。

最后,由边界类对象向外系统反馈信息,完成一个交互回合。


[架构师强化]10月9-11晚8点企业应用架构模式新解-网络公开课
[3级(片?)]类的精细建模高阶-10月16-18晚8点网络公开课
[EA-029/石油钻井管理平台]35套UML/SysML+EA/StarUML的建模示范视频-全程字幕
如何选择UMLChina服务
作者微信:umlchina2
继续滑动看下一个

《软件方法(下)》第8章2023版连载(04)面向对象的假设

潘加宇 UMLChina
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存