2

我对在类似 CRUD 的操作上应用 Larman 的系统操作合同(来自应用 UML 和模式一书中的 OO 分析)有些困惑。更准确地说,我对后置条件部分感到困惑。

例如,如果我的 CRUD 系统操作如下所示:

createEmployee(employee:Employee), 
readEmployee(employeeId:int), 
updateEmployee(employee:Employee), 
deleteEmployee(employeeId:int)

例如,readEmployee系统操作或其他类似操作的后置条件是什么searchEmployees

例如:对于读取操作,系统需要从数据库中读取记录,实例化域对象,在域对象上设置属性值(也设置关系),仅此而已。这是否意味着上面提到了后置条件-实例创建,属性更改等。或者,读取操作没有任何后置条件。这些对我来说都不合逻辑。

我的困惑是关于域模型(状态)和数据库(状态)之间的关系。我只是没有得到上述操作对域模型的影响。我一直认为数据库是保存系统状态的地方。创建员工后,其对象的状态将保存在数据库中......但是域模型状态会发生什么?

4

3 回答 3

0

后置条件定义了您的应用程序(或对象,取决于抽象级别)在操作之后应该处于什么状态才能被视为成功。例如,对于该readEmployee操作,后置条件是:

  • 创建一个新Employee实例。
  • Employee实例包含与数据库值匹配的属性。
  • 数据库连接已关闭。

我喜欢将“前置条件”和“后置条件”分别视为您的应用程序在执行操作之前和之后的“心态”。可以想象,当您进行 DbC 时,这更像是一个思考过程,而不是编码练习。

(如果您进行单元测试,状态会清楚地表明您的测试需要涵盖哪些内容。基本上,您最终会测试应用程序的“心态”。)

有趣的是,如果您考虑 DbC 的反面,您会意识到要确定您的应用程序(或对象)应该公开哪些操作,只需列出它可以拥有的状态以及它如何在这些状态之间转换。进行这些转换所需采取的操作将成为您的操作,您不必费心实施不会导致任何所需状态的操作。因此,例如,您可能希望您的应用程序具有以下状态。

  • 添加了员工详细信息 (S1)
  • 已加载员工详细信息 (S2)
  • 更新了员工详细信息 (S3)
  • 删除员工详细信息 (S4)

以下状态转换是可能的。

  • S1 -> S3(添加新员工,更新详细信息)
  • S1 -> S4(添加新员工,删除员工)
  • S2 -> S3(加载员工详细信息,更新员工详细信息)
  • S2 -> S4(加载员工详细信息,删除员工)
  • S4 -> S1(删除员工,添加新员工)
  • S2 -> S1(加载员工详细信息,添加新员工)
  • S3 -> S1(更新员工详细信息,添加新员工)
  • S3 -> S2(更新员工详细信息,加载员工详细信息)

基于上述内容,您可以以只允许有效转换的方式编写操作,而其他任何事情都会导致错误。

不可能的状态转换:

  • S4 -> S2(不能删除员工,然后加载他们的详细信息)
  • S4 -> S3(不能删除员工,然后更新他们的详细信息)

状态建模可能是设计对象中最重要的部分,因此您提出了正确的问题。如果您想要关于状态建模的良好资源,请从 Sally Shlaer / Stephen Mellor获取Object Lifecycles Modeling the World in States 。这是一本相当古老的书,在亚马逊上几乎不花钱,但它介绍的原则构成了现代 UML 的基础——顺便说一下,书中使用的符号看起来一点也不像 UML。

我意识到我没有触及数据库状态,但在概念层面上,数据库层只是另一个状态系统,并且适用相同的原则。

我希望这很有用。

于 2012-04-18T23:33:23.823 回答
0

我对拉曼契约的解释总是与领域模型有关。Larman 明确指出只有 5 种后置条件:

  1. 实例创建
  2. 实例删除
  3. 属性值的变化。
  4. 协会成立。
  5. 协会破裂。

因此,读取(或搜索)操作将没有后置条件,至少在正在读取或搜索的元素上没有。例如,如果 10,000 个用户在一天内执行读取/搜索,但从未执行任何其他操作(C、U、D),则域中的对象不会发生变化。

但是,在记住搜索/读取的域中,有一个例外。例如,谷歌肯定会跟踪搜索。在这种情况下,进行搜索具有在其域模型中创建新对象的后置条件,例如,创建了一个搜索实例s (实例创建)

于 2015-06-29T20:39:30.550 回答
0

令人困惑的是,Larman 提供的合同模板中提到了数据模型关系,如下所示:

Contract CO2: enterItem
Operation: enterItem(itemID : ItemID, quantity : integer)
...
sli was associated with a ProductSpecification, based on itemID match (association formed).

操作合同中不应提及数据库的详细引用属性。最好将其保留为:“sli 与 ProductSpecification 相关联”。

事实上,这也是拉尔曼的运营合同中没有多谈的事情之一。考虑一个计算项目总数并返回总数的操作的合同!好像不能写成运营合同。

于 2015-10-14T19:45:03.347 回答