干净的架构当前用户获取
Clean architecture current user acquisition
在 Clean Architecture 用例中是否应该注意 authentication/authorization 进程和 command/query 层应该使用一些框架在下面的层中实现身份验证服务的一些抽象,或者用户标识符应该作为传递command/query?
的部分
选项:
选项 1:
class ChangePasswordCommand {
char[] newPassword;
}
class ChangePasswordCommandHandler {
AuthService authService;
void handle(ChangePasswordCommand command) {
User currentUser = authService.currentUser();
// logic
}
}
选项 2:
class ChangePasswordCommand {
UUID userId;
char[] newPassword;
}
class ChangePasswordCommandHandler {
UserRepository userRepository;
void handle(ChangePasswordCommand command) {
User currentUser = userRepository.findById(command.getUserId());
// logic
}
}
当您谈论用例时,这是您的应用程序的领域。
所以,要回答这个问题,我可以说:这取决于这个领域。
如果您的域是关于“用户管理”的(例如:LDAP 应用程序),是的!您需要在您的域中实施它。
否则,这只是一个技术问题,您可以在域外管理它(并直接调用存储库)。
示例:
假设您有一些第三方身份验证提供商提供具有以下字段的用户结构:id、电子邮件地址等。
如果没有业务规则只对用户进行身份验证,您可以从应用层调用放置在基础层的身份验证器。
userApplication.authenticate(String login, String password) {
userProvider.authenticate(login, password);
}
另一方面,如果你想在认证用户时应用一些业务规则,你必须从应用层调用用户域API(接口放在域层)。
以下代码只是一个示例。你必须清理它。
应用层:
userApplication.authenticate(String login, String password) {
userAPI.authenticate(login, password);
}
领域层:
class Member {
...
}
interface UserAPI {
Member authenticate(login, password);
}
*您可以通过创建一些工厂或服务或任何您想要的方式来实现此接口。假设您有一个域用户服务。
class UserService implements UserAPI {
UserSPI userSPI;
Member authenticate(login, password) {
// apply some business rules
userSPI.authenticate(login, password);
}
}
interface UserSPI {
Member authenticate(login, password);
}
基础设施层:
class MemberDTO {
...
}
class userProvider implements UserSPI {
private final RemoteProvider remoteProvider;
Member authenticate(login, password) {
MemberDTO memberDTO = remoteProvider.authenticate(login, password);
return memberMapper.dtoToDomain(memberDTO);
}
}
在 Clean Architecture 用例中是否应该注意 authentication/authorization 进程和 command/query 层应该使用一些框架在下面的层中实现身份验证服务的一些抽象,或者用户标识符应该作为传递command/query?
的部分选项:
选项 1:
class ChangePasswordCommand {
char[] newPassword;
}
class ChangePasswordCommandHandler {
AuthService authService;
void handle(ChangePasswordCommand command) {
User currentUser = authService.currentUser();
// logic
}
}
选项 2:
class ChangePasswordCommand {
UUID userId;
char[] newPassword;
}
class ChangePasswordCommandHandler {
UserRepository userRepository;
void handle(ChangePasswordCommand command) {
User currentUser = userRepository.findById(command.getUserId());
// logic
}
}
当您谈论用例时,这是您的应用程序的领域。 所以,要回答这个问题,我可以说:这取决于这个领域。
如果您的域是关于“用户管理”的(例如:LDAP 应用程序),是的!您需要在您的域中实施它。
否则,这只是一个技术问题,您可以在域外管理它(并直接调用存储库)。
示例:
假设您有一些第三方身份验证提供商提供具有以下字段的用户结构:id、电子邮件地址等。
如果没有业务规则只对用户进行身份验证,您可以从应用层调用放置在基础层的身份验证器。
userApplication.authenticate(String login, String password) {
userProvider.authenticate(login, password);
}
另一方面,如果你想在认证用户时应用一些业务规则,你必须从应用层调用用户域API(接口放在域层)。
以下代码只是一个示例。你必须清理它。
应用层:
userApplication.authenticate(String login, String password) {
userAPI.authenticate(login, password);
}
领域层:
class Member {
...
}
interface UserAPI {
Member authenticate(login, password);
}
*您可以通过创建一些工厂或服务或任何您想要的方式来实现此接口。假设您有一个域用户服务。
class UserService implements UserAPI {
UserSPI userSPI;
Member authenticate(login, password) {
// apply some business rules
userSPI.authenticate(login, password);
}
}
interface UserSPI {
Member authenticate(login, password);
}
基础设施层:
class MemberDTO {
...
}
class userProvider implements UserSPI {
private final RemoteProvider remoteProvider;
Member authenticate(login, password) {
MemberDTO memberDTO = remoteProvider.authenticate(login, password);
return memberMapper.dtoToDomain(memberDTO);
}
}