【问题标题】:Clean Architecture - Robert Martin - Use Case Granularity清洁架构 - Robert Martin - 用例粒度
【发布时间】:2016-05-07 10:15:56
【问题描述】:

我正在考虑在一个项目中实现 Robert Martin 的 Clean Architecture,我正在尝试找出如何处理重要的用例。

我发现很难将架构扩展到复杂/组合的用例,尤其是参与者是系统而不是用户的用例,例如在执行某种批处理的系统中。

为了说明的目的,让我们假设一个用例,如“系统更新所有账​​户余额”,用伪代码实现,如

class UpdateAllAccountBalancesInteraction {
    function Execute() {
        Get a list of all accounts
        For each account
            Get a list of all new transactions for account
            For each transaction
                Perform some specific calculation on the transaction
            Update account balance
    }
}

此外,“获取所有账户的列表”、“获取账户所有新交易的列表”、“对交易执行一些特定的计算”、“更新账户余额”都是它们自己的有效用例并且它们中的每一个都已经在自己的交互类中实现了。

出现了几个问题:

  • 用例“系统更新所有帐户余额”是否有效 用例还是应该分解成更小的用例(尽管 从商业的角度来看,这似乎是有道理的,它是一个 合法的业务场景)?
  • 是 UpdateAllAccountBalancesInteraction 合法的互动?
  • 是否允许/应该协调其他交互?
  • 是编排其他的代码 互动真的属于其他地方吗?
  • 是否可以 UpdateAllAccountBalancesInteraction 作为交互,但有它 调用其他交互者共享的函数,而不是充当 其他交互者的协调者?

【问题讨论】:

    标签: oop architecture software-design


    【解决方案1】:

    我的建议是以不同的方式解决问题。在域模型中表示问题本身,而不是使用过程方法。您看到了用例的一些问题,其中之一是它们的粒度通常是不确定的。

    在域模型中,表示特定事物(即“帐户”)的标准方式是使用两个对象。一个代表特定帐户,一个关联对象代表所有帐户共有的那些东西。

    AccountCatalog (1) ---- (*) SpecificAccount
    

    在您的示例中,SpecificAccount 将有一个服务(方法)“UpdateBalance”。 AccountCatalog 有一个服务(方法)“UpdateAllBalances”,它会向其集合中的所有 SpecificAccounts 发送一条消息 UpdateBalance。

    现在任何东西都可以发送 UpdateAllBalances 消息。另一个对象、人类交互或另一个系统。

    我应该注意,帐户“知道”(即维持)自己的余额而不是被告知更新是很常见的。

    【讨论】:

    • Clean Architecture 方法也建议使用域模型,正如您所描述的那样。这是一个定义实体和企业业务规则的域模型,不依赖于其他任何东西。此外,它建议在域模型之上的一个层,实现应用程序业务规则,并将用例实现为依赖于类似于命令设计模式的接口的类。我的问题是关于最后一层的构图。
    【解决方案2】:

    显然,您有一个新的高级交互,它与低级交互共享一些(或许多)通用功能。没关系。

    如果业务需要一个名为 UpdateAllAccountBalances 的用例,那么它是一个有效的用例,最好以反映业务逻辑的方式命名它。

    没关系。一个交互调用其他交互,如果这准确地反映了您的业务逻辑。问自己以下问题:如果 UpdateAccountBalance 的要求发生变化,这是否也会以完全相同的方式影响UpdateAllAccountBalances?如果答案是肯定的,那么实现此目的的最佳方法是让UpdateAllAccountBalances 调用UpdateAccountBalance,因为否则,您需要在两个地方进行更改以保持一致。如果答案是否定的,那么您想解耦这两个交互,这可以通过让它们调用共享函数来完成。

    【讨论】:

    • 我必须下定决心继续我的项目,所以我得出结论,演示文稿中提供的示例/article 是微不足道的,我认为依赖分离是指层级这很容易达成一致。考虑到这一点,我得出结论,一个交互的Execute() 方法不应该调用另一个交互的Execute() 方法,但它们绝对可以在同一层共享代码。
    猜你喜欢
    • 2015-05-07
    • 2022-05-18
    • 1970-01-01
    • 2021-10-16
    • 2017-03-20
    • 2018-06-15
    • 2016-09-17
    • 1970-01-01
    • 2020-03-02
    相关资源
    最近更新 更多