php - 如果业务逻辑要发送电子邮件
问题描述
我正在尝试实现鲍勃叔叔的清洁架构:
除了用例/交互器之外,一切都很好。我需要注册一个用户,所以我需要RegisterUser
UseCase。在具体的交互器中,我实现了RegisterUser
只创建实体并使用端口User
散列其密码的用例。PasswordBroker
创建用户后,我需要发送一封验证电子邮件。为此,我需要使用框架的组件。并且有两个主要问题。
- 我认为为邮件服务编写端口是没有意义的,因为这个端口只是框架服务的巨大复制/粘贴抽象
- 创建用户后,Interactor 无法发送电子邮件,因为用户最终将存储在
flush()
控制器内部的 Doctrine 之后。当我们发送电子邮件但用户未存储在数据库中时,存在风险。它必须是一致的。
在这种情况下,最好的方法是什么?
我认为我们需要某种与具体用例相关的端口,该端口将在用例结束时调用,并在框架的 Mailer 和 Doctrine 可用的应用层中实现。
解决方案
- 我认为为邮件服务编写端口是没有意义的,因为这个端口只是框架服务的巨大复制/粘贴抽象
我将创建一个Notification
传递给用例交互器的接口,类似于EntityGateway
or EntityRepository
。
我会Notification
以一种从具体通知机制中抽象出来的方式来设计界面,例如电子邮件、信使等。
然后Notification
可能看起来像这样:
public interface Notification {
public void notifyUserRegistered(User user);
}
实现将放置在外层,通常是接口适配器层。因为这是适应内层接口的层——因此得名。
这样的Notification
接口可以很容易地在测试中模拟,这可以让你的测试保持快速。因此,我不认为通知界面是一个巨大的复制/粘贴抽象。
- 用户创建后交互器无法发送电子邮件,因为用户最终将在控制器内部的 Doctrine flush() 之后存储。当我们发送电子邮件但用户未存储在数据库中时,存在风险。它必须是一致的。
首先,我想您无论如何都不能强制执行,因为发送电子邮件不参与数据库事务。因此,您仍然会遇到一致性问题。
但是您通常可以注册活动事务,以便在成功完成时收到通知。这意味着Notification
实现将只注册一个在事务完成时调用的回调。然后,您可以发送电子邮件。
我不知道如何在 php 中完成,也许这是 SO 上的另一个问题。在 Java 中,有几种方法取决于您使用的事务 api。
对于 Spring,请查看Transaction 绑定事件或 JEE 的TransactionSynchronizationRegistry。如果 Java 开发人员读过这篇文章,请提及一些。
推荐阅读
- c# - 如何实现 ImageButtons 的绑定,以便仅在加载图像后显示图像?
- postgresql - 检查我在表中的点(字段)总和是否大于表中所有其他人的点总和。很少有活动
- r - 如何编写一个 apply() 函数来将矩阵列中的每个元素限制为最大允许值?
- .net-6.0 - 如何删除 Microsoft.NETCore.App 6.0.0-rc.2.21480.5
- javascript - Nextjs中获取客户端IP
- python - 如何在没有前缀的单独文件中使用 python 函数
- image - 图像属性检测 API
- python - 具有多个参数的 read_excel 循环
- ruby-on-rails - 使用延迟作业从 rails 5.2.4 升级到 6.1 - 作业没有被拾取
- sql-server - EXEC 是否在 TRY/CATCH 块中提交事务?