0

我有一个Document类需要在保存到数据库之前进行外部授权。

可以创建一个authorize像...这样的方法吗?

class Document:
    authorize(IExternalAuthorizator authorizator):
        authorization_result = authorizator.authorize(this)
        // update internal state with result...

然后在用例或服务中使用它...

class UseCase:
    execute(IDocumentRepository repo, IExternalAuthorizator authorizator):
        doc = new Document()
        doc.authorize(authorizator)
        repo.save(doc)

还是我应该有这样的Document课......

class Document:
    authorize(AuthorizationResult result):
        // update internal state with result...

然后用例......

class UseCase:
    execute(IDocumentRepository repo, IExternalAuthorizator authorizator):
        doc = new Document()
        result = authorizator.authorize(doc)
        doc.authorize(result)
        repo.save(doc)

还是没有,只有第三种选择?

有什么帮助吗?

4

1 回答 1

2

根据我自己对文献的研究

  • 第二种形式更好
  • 两者之间的差异很小。

你的领域模型本质上是一个状态机:它有自己的一些信息,新信息到达,模型决定如何将新信息与它已经知道的信息集成。

当我们需要一些额外的信息以使模型继续进行时,通常会引入额外的端口,而这些信息在其他地方

其他地方的信息的问题是,在我们想要它的那一刻,信息可能不可用(也许授权无法用于升级)。

所以一个合乎逻辑的问题是:这些接口中哪一个更适合异步信息交换?

当然,如果我们努力将域模型与持久性解决方案隔离开来避免代码混乱,那么出于同样的原因,我们也应该将域模型与异步消息检索隔离开来。该代码是管道世界的一部分,在我们编写域计算时根本不相关。

实际上,让应用程序担心与 Authorization 协商意味着,当授权不可用时,应用程序可以继续处理其他工作,并在授权数据可用时返回此特定文档。域模型本身没有(也不应该)有这样做的上下文。

以不同的方式表达相同的想法,领域模型的“单一职责”是簿记,而不是信息检索。

另请注意,这两种方法不一定有太大不同:

class Document:
    authorize(IExternalAuthorizator authorizator):
        authorization_result = authorizator.authorize(this)
        this.authorize(authorization_result)

    authorize(AuthorizationResult result):
        // update internal state with result...

或者

class UseCase:
    execute(IDocumentRepository repo, IExternalAuthorizator authorizator):
        doc = new Document()
        authorize(doc, authorizator)
        repo.save(doc)

    authorize(Document doc, IExternalAuthorizator authorizator):
        authorization_result = authorizator.authorize(doc)
        doc.authorize(authorization_result)

简而言之:除了小数据检索部分之外,这两种情况都是一样的。当数据检索微不足道时,这不会产生影响,但随着越来越多的管道问题被引入,它会产生影响。

于 2020-07-19T04:25:17.470 回答