【问题标题】:Larman's System Operation Contracts - CRUD exampleLarman 的系统操作合同 - CRUD 示例
【发布时间】:2011-02-16 19:01:13
【问题描述】:

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

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

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

什么是后置条件,例如,readEmployee 系统操作,或其他一些操作,如 searchEmployees 等?

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

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

【问题讨论】:

    标签: oop contract operation system


    【解决方案1】:

    后置条件定义了您的应用程序(或对象,取决于抽象级别)在操作后应处于何种状态才能被视为成功。例如,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。

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

    我希望这很有用。

    【讨论】:

      【解决方案2】:

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

      1. 实例创建
      2. 实例删除
      3. 属性值变化。
      4. 协会成立。
      5. 关联中断。

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

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

      【讨论】:

        【解决方案3】:

        Larman 提供的合同模板中的数据模型关系令人困惑:

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

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

        其实这也是Larman的运营合同中没有详细谈及的事情之一。考虑一个计算项目总数并返回总数的操作的合同!好像不能写成运营合同。

        【讨论】:

          猜你喜欢
          • 2015-09-16
          • 1970-01-01
          • 1970-01-01
          • 2015-03-20
          • 1970-01-01
          • 1970-01-01
          • 2014-10-15
          • 2014-10-22
          • 1970-01-01
          相关资源
          最近更新 更多