我正在考虑在一个项目中实施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
}
}
此外,"获取所有帐户的列表","获取帐户的所有新交易列表","对交易进行一些特定计算" ;,"更新帐户余额"都是他们自己的有效用例,每个用例都已经在自己的交互类中实现。
出现了一些问题:
答案 0 :(得分:1)
显然,您有一个新的高级别互动,与较低级别的互动共享一些(或许多)常见功能。没关系。
如果业务需要一个名为UpdateAllAccountBalances
的用例,那么它就是一个有效的用例,并且以反映业务逻辑的方式命名它是件好事。 / p>
它是o.k.如果这可以准确反映您的业务逻辑,则可以进行一次交互以调用其他交互问自己以下问题:如果UpdateAccountBalance的要求发生变化,这是否也会以完全相同的方式影响UpdateAllAccountBalances
?如果答案是肯定的,那么实现此目标的最佳方法是UpdateAllAccountBalances
调用UpdateAccountBalance
,否则,您需要在两个地方进行更改才能保持一致。如果答案是否定的,那么你想要解耦两个交互,这可以通过让它们调用共享函数来完成。
答案 1 :(得分:0)
我的建议是以不同方式解决问题。在域模型中表示问题本身,而不是使用过程方法。您看到了用例的一些问题,其中之一就是它们的粒度通常是不确定的。
在域模型中,表示特定事物(即“帐户”)的标准方式是使用两个对象。一个代表特定帐户,一个代表所有帐户共有的相关对象。
AccountCatalog (1) ---- (*) SpecificAccount
在您的示例中,SpecificAccount将具有服务(方法)“UpdateBalance”。 AccountCatalog有一个服务(方法)“UpdateAllBalances”,它将UpdateBalance消息发送到其集合中的所有SpecificAccounts。
现在任何东西都可以发送UpdateAllBalances消息。另一个对象,人际互动或其他系统。
我应该注意,一个帐户“知道”(即维持)自己的余额,而不是被告知要更新,这是很常见的。