You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

整洁架构下通知系统邮件内容渲染与持久化方案问询

通知子域的表示层集成与持久化方案疑问

问题描述

我负责的系统中有一个通知子域,基于系统其他部分的集成事件处理并发送所有邮件与SMS通知。每个用例在应用层创建通知实体,通过基础设施层的通知仓库保存(保存的通知进入队列,最终由定时任务发送),通知创建代码示例如下:

$notification = Notification::create(
            Channel::EMAIL,
            $recipients,
            $subject,
            $content,
            $context
        );

邮件内容多为非纯文本,此部分属于UI/表示层范畴,我困惑于应用层如何获取该内容而不破坏控制流?


更新补充

查阅相关文献后我有了一些进展,先补充通知的使用场景:通知初始会发送给收件人(如订单确认邮件发给客户、员工手动发送消息、订单取消邮件等,支持邮件与SMS渠道);管理界面中员工/管理员需查看特定实体(如订单)的通知历史,包括收件人、发送时间、状态(排队、已发送、错误),通知需永久持久化。

针对初始的表示层问题,我为每种通知引入了Presenter接口,接口置于应用层(或应放在领域层?),具体实现则在UI层。例如订单确认通知有OrderConfirmationPresenterInterface接口,包含present方法。目前通过依赖注入(DI)注入接口实现,用于创建通知实体:

$notification = Notification::create(
            Channel::EMAIL,
            $recipients,
            $subject,
            $this->emailPresenter->present($orderId, $something, $somethingElse),
            $context
        );

即由Presenter返回实际生成的表示内容(通常为HTML格式的邮件内容),作为字符串加入通知实体并持久化到数据库中。我想确认此实现路径是否正确?

此外还有一个疑问:创建通知实体时,应持久化已生成的表示内容,还是仅持久化输入数据、在发送通知时再生成表示内容?前者能确保留存通知的实际呈现样式,但会导致每条记录重复存储HTML;后者仅存储数据,但后续若修改表示逻辑,查看历史通知时的渲染结果可能与最初发送给客户的内容不一致。


解答

一、Presenter接口的实现路径合理性

你的方案是合理的,接口的放置位置建议放在应用层而非领域层:

  • 领域层应聚焦核心业务规则,通知的内容渲染属于"如何呈现"的表示逻辑,不属于领域核心规则,放在应用层更合适,能保持领域层的纯净性。
  • 应用层作为领域层与UI层的中间层,定义Presenter接口可以实现依赖反转:应用层依赖抽象接口,UI层实现具体的渲染逻辑,既不破坏控制流(依赖方向是UI层→应用层,而非应用层直接依赖UI层),也符合端口与适配器的设计思想——应用层定义端口(Presenter接口),UI层作为适配器实现端口。

二、持久化内容 vs 持久化输入数据的选择

两种方案各有优劣,需结合业务需求权衡:

持久化已生成的表示内容(HTML)

  • 优势:完全保证历史通知与发送给用户的内容一致,管理员查看历史时能看到用户实际收到的样式,符合审计和回溯需求;发送时无需再次渲染,减少计算开销。
  • 劣势:存储体积更大,尤其是HTML内容可能包含重复的样式代码;如果后续需要批量修改历史通知的样式(业务上基本很少有这种需求),无法通过修改模板实现,只能批量更新数据库记录。

持久化输入数据,发送时再渲染

  • 优势:存储体积小,仅保存核心数据;后续修改模板样式时,新发送的通知会自动应用新样式。
  • 劣势:历史通知的渲染结果可能与用户实际收到的不一致,尤其是当模板逻辑或依赖的外部数据(如品牌标识、政策文本)发生变化时,会破坏通知的历史真实性;发送时需要重复执行渲染逻辑,增加一定的计算成本。

推荐方案:如果系统对通知历史的真实性要求较高(比如电商订单通知、合规类通知),优先选择持久化已生成的表示内容。可以通过对HTML内容进行压缩(比如去除多余空格、合并CSS)来降低存储开销;如果业务对存储成本敏感,且通知历史的样式一致性要求不高,再考虑仅存储输入数据。


内容的提问来源于stack exchange,提问作者Tor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 08:35:03