现在您有了由实体、值对象和服务所形成的模型,你也知道这些元素需要彼此交互,以实现业务执行的各种行为。作为一个软件工匠,你有责任以这样一种方式来对这种交互进行建模,不仅可以理解下面的硬件,也可以理解古怪的人类思想。这种交互需要反映底层业务语义,并且必须包含您正在建模的问题领域的词汇表。这里说的通过词汇表,我所指的是参与的对象的名称以及作为用例的一部分执行的行为。领域的词汇表的使用需要被传递到更小的抽象中去。您可以编写一个AccountService实现(这是一个领域服务)如下:

trait AccountService {

def debit(a: Account, amount: Amount): Try[Account] = //..

def credit(a: Account, amount: Amount): Try[Account] = //..

def transfer(from: Account, to: Account, amount: Amount) = for {

d

<

  • debit(from, amount)

c

<

  • credit(to, amount)

} yield (d, c)

}

让我们更详细地了解一下这个实现是如何体现在可理解性的特性上的:

  • 函数体是最小的,不包含任何无关的细节。它只是封装了在两个帐户之间的资金转移所涉及的领域逻辑

  • 这个实现使用来自银行领域的术语,因此熟悉业务领域的人不知道底层实现平台的任何信息,也应该能够理解正在发生的事情。

  • 这个实现描述了执行乐观状态下的处理方式(即没有出现异常的情况下)。异常的方式被完全封装在用于实现的抽象中。如果你知道Scala,这里使用的for循环是一元的,并且会处理在执行序列中可能发生的任何异常。随着我们的进展,我们将讨论其中的许多问题。

PS:Scala中,for循环时一个可以完成filter/map/reduce的语法糖。更多知识看一下scala的相关书籍。

Eric Evans称呼这为ubiquitous language(统一语言)。在你的模型中使用领域词汇表,使这些术语交互,就类似于在该领域所说的语言一样。从正确命名实体和原子行为开始,把这个词汇表扩展到你用它们组成的更大的抽象上。不同的模块会说不同的方言,而同一术语在不同的限界上下文中也意味着不同的事情。但在上下文中,词汇应该是清晰而明确的。

拥有一种一致的通用语言与设计您的模型的适当的api有很大关系。这些API必须具有表达性,这样一个领域的专家才能通过只查看API来理解上下文。这被称为领域特定语言(DSL)。

results matching ""

    No results matching ""