我有一个通知子域,其中所有电子邮件和短信通知都是根据系统其他部分的集成事件从系统处理/发送的。
每个用例都会在应用程序层创建一个通知实体,并使用基础设施中的通知存储库保存它。 (保存的通知将排队并最终由计划作业发送)。
通知可能如下所示:
$notification = Notification::create(
Channel::EMAIL,
$recipients,
$subject
$content
$context
);
在很多情况下,电子邮件内容不仅仅是纯文本,这就是我的问题所在。电子邮件内容是一个表示问题,并且应该驻留在 UI/表示层中?用例/应用程序层如何在不破坏控制流的情况下得到这个?
我会根据我对您当前设计的理解来表达我的答案,即:
(我将这些有界上下文称为子域,因为我认为您选择此设计是基于某些便利,而不是因为这是从业务中出现的实际子域。它是解决方案的一部分,而不是问题的一部分。)
如果是这种情况,那么在我看来,电子邮件可能是您专用于通知的有界上下文的域模型中的实体。在这种情况下,电子邮件的文本驻留在域模型中,因为它是构成电子邮件实体的一部分。您甚至可以决定在域模型中应用一些不变量,具体取决于此类文本的完成方式或它如何根据某些操作进行更改;不变量将在您的域模型中建模。
对于表示层,你可以将其视为纯粹的表示,即从领域语言到其他语言(REST、UI…)的翻译器。这种模式的采用和启发来自 Alistair Cockburn 的六角形架构,并由 DDD 社区重新解释(请参阅 Khononov 的书作为参考):来自/到其他系统的驱动程序和从动端口仅仅是这些系统语言的翻译器。在您的情况下,接受电子邮件并将其转换为实际电子邮件消息的表示层确实是外部系统的适配器,因此其目的是将电子邮件从域模型转换为编码的电子邮件消息,并将其发送到外部系统(无论您使用什么来发送消息)。
—-
请注意,正如最后一条评论,您实现的内容与发件箱模式类似:每次您的域中发生有意义的事情时,都会将新通知存储在某处,准备重新处理(在您的情况下,以电子邮件形式发送) .
在某些解释中,此模式是直接在域而不是应用程序层中实现的(再次参见 Khononov 以供参考)。
在任何情况下,都可以实现适当的发件箱模式,以便每次将东西放入发件箱时,都是以事务方式完成的。