横向层调用设计问题
Sideways layer calls design issue
我有一个分层应用程序,其中 UI -> 服务 -> 逻辑 -> DA。我正在使用控制反转和 Unity 作为我的 IoC 容器。
下面是我遇到的一个常见问题,我正在寻找可以接受的问题或解决方法。
在正常流程(红色箭头)中,以登录为例,UI 调用 UserService class,后者调用 Userlogic class,后者调用进入数据库的 UserDataAccess class。数据返回(也许)返回逻辑,在那里处理它,然后回复返回到 UI.
但是蓝线 - 是糟糕的架构吗?那里发生的事情是我正在注册一个新用户。 UI 调用 UserService (_userService.RegisterNewUser),后者调用 Logic,后者将用户注册到数据库,并用新的 UserID 回复 Logic。
如果一切顺利,我需要为新用户创建一条 'Finance' 记录(这是业务需求)。然后我调用我的 _FinanceLogic class (_FinanceLogic.CreateUserFinance),然后它会进入数据库并一直响应返回到 UserLogic,然后完成注册,如果一切都是好的
我想知道的是 - 跨层调用(_UserLogic 调用 _FinanceLogic)是否可以接受?我需要为 _FinanceLogic class 添加对我的 _UserLogic 的引用。这意味着我的构造函数越来越大。
public UserLogic(ILog logger, IEmail email, IUserData user, IFinancialLogic financialLogic)
或者,_UserLogic 应该直接调用 _FinanceDataAccess 吗?我怀疑不是,因为 _FinanceLogic.CreateUserFinance 中存在您不想绕过的逻辑。
是的,你完全可以横向调用。有问题的蓝色箭头是 Logic
层上的横向调用。一般来说,只要您保持在同一抽象层上,进行横向调用是绝对可以的 - 在这种情况下您就是这样做的。
但是,从设计的角度来看,我不确定调用是否在正确的层中。 Service
层和Logic
层很难区分,但在我看来,业务逻辑编码在Service
层。因此,当您正确地将财务记录创建识别为业务需求时,您应该触发服务层的形式(因为它可能包含所有业务逻辑)。
备选设计:基于事件的架构
您可能想要利用 event-based architecture,在其中使用事件对业务逻辑流进行编码。通常,您用过去时命名事件以反映它们已经发生的事实。您现在可以定义以下事件:
UserAccountCreatedEvent
:帐户存储在数据库中后立即发出
FinanceRecordCreatedEvent
:财务记录存储在数据库中后立即发出。
UserRegisteredEvent
:注册的所有必需步骤完成后立即发出(即上述两个事件)。
您所需要的只是一个事件库,它允许您为不同的事件定义侦听器。通过这样的设置,将来很容易实施更改。您可以轻松添加一个 ConfirmationEmailListener
来为每个 UserAccountCreatedEvent
.
发送一封确认电子邮件
我有一个分层应用程序,其中 UI -> 服务 -> 逻辑 -> DA。我正在使用控制反转和 Unity 作为我的 IoC 容器。
下面是我遇到的一个常见问题,我正在寻找可以接受的问题或解决方法。
在正常流程(红色箭头)中,以登录为例,UI 调用 UserService class,后者调用 Userlogic class,后者调用进入数据库的 UserDataAccess class。数据返回(也许)返回逻辑,在那里处理它,然后回复返回到 UI.
但是蓝线 - 是糟糕的架构吗?那里发生的事情是我正在注册一个新用户。 UI 调用 UserService (_userService.RegisterNewUser),后者调用 Logic,后者将用户注册到数据库,并用新的 UserID 回复 Logic。
如果一切顺利,我需要为新用户创建一条 'Finance' 记录(这是业务需求)。然后我调用我的 _FinanceLogic class (_FinanceLogic.CreateUserFinance),然后它会进入数据库并一直响应返回到 UserLogic,然后完成注册,如果一切都是好的
我想知道的是 - 跨层调用(_UserLogic 调用 _FinanceLogic)是否可以接受?我需要为 _FinanceLogic class 添加对我的 _UserLogic 的引用。这意味着我的构造函数越来越大。
public UserLogic(ILog logger, IEmail email, IUserData user, IFinancialLogic financialLogic)
或者,_UserLogic 应该直接调用 _FinanceDataAccess 吗?我怀疑不是,因为 _FinanceLogic.CreateUserFinance 中存在您不想绕过的逻辑。
是的,你完全可以横向调用。有问题的蓝色箭头是 Logic
层上的横向调用。一般来说,只要您保持在同一抽象层上,进行横向调用是绝对可以的 - 在这种情况下您就是这样做的。
但是,从设计的角度来看,我不确定调用是否在正确的层中。 Service
层和Logic
层很难区分,但在我看来,业务逻辑编码在Service
层。因此,当您正确地将财务记录创建识别为业务需求时,您应该触发服务层的形式(因为它可能包含所有业务逻辑)。
备选设计:基于事件的架构
您可能想要利用 event-based architecture,在其中使用事件对业务逻辑流进行编码。通常,您用过去时命名事件以反映它们已经发生的事实。您现在可以定义以下事件:
UserAccountCreatedEvent
:帐户存储在数据库中后立即发出FinanceRecordCreatedEvent
:财务记录存储在数据库中后立即发出。UserRegisteredEvent
:注册的所有必需步骤完成后立即发出(即上述两个事件)。
您所需要的只是一个事件库,它允许您为不同的事件定义侦听器。通过这样的设置,将来很容易实施更改。您可以轻松添加一个 ConfirmationEmailListener
来为每个 UserAccountCreatedEvent
.