DDD领域驱动设计实战(六)-领域服务,mysql索引教程

本文探讨了在领域驱动设计(DDD)中如何避免过度使用领域服务导致贫血模型,以用户认证为例。指出认证过程应包含对Tenant活跃状态的检查,强调认证操作不应放在实体中。提出了将认证过程集中在领域服务中以保持模型的纯净,减少客户端职责,并确保通用语言的准确性。文章还讨论了不同认证实现方式的优缺点,并提供了建模领域服务的建议。
摘要由CSDN通过智能技术生成

过度使用领域服务将导致贫血领域模型,即所有业务逻辑都位于领域服务中,而非实体和值对象

来看使用领域服务案例:

案例


User认证

考虑身份与访问上下文,对一个User进行认证。

  • 系统必须对User进行认证,并且只有当Tenant处激活状态时才能对User进行认证。

为什么领域服务在此时是必要的呢?难道不可以简单地将该认证操作放在实体?从客户角度来看,我们可能会使用以下代码实现认证:

// client finds User and asks it to authenticate itself

boolean authentic = false;

User user = DomainRegistry

.userRepository()

.userWithUsername(aTenantld, aUsername);

if(user != null) {

authentic = user.isAuthentic(aPassword);

}

return authentic;

以上设计至少存在如下问题

  • 客户端需要知道某些认证细节

他们需要找到一个User,然后再对该User进行密码匹配

  • 这种方法也不能显式表达通用语言

这里,我们询问的是一个User "是否被认证”,而没表达“认证”这个过程。在有可能的情况下,我们应尽量使建模术语直接表达出团队成员的交流用语,但还有更糟糕的。

这种建模方式并不能准确表达出团队成员所指的“对User进行认证”的过程。它缺少了 “检查Tenant否处于激活状态”这个前提条件。如果一个User所属的Tenant处于非激活状态,我们便不应该对该User进行认证。

或许可以通过以下方法予以解决:

这种方式的确对Tenant的活跃性做了检查,同时我们也将User#isAuthentic换成Tenant#authenticate

但这种方式也有问题:

  • 此时客户端需知道更多认证细节,而这些他们不应该知道。当然,可以将

Tenant#isActive放在authenticate,但这并不是一个显式的模型。同时这将带来另外一个问题,即此时的Tenant需要知道如何对密码进行操作。

回忆一下该认证过程的另一个需求:

  • 必须对密码进行加密,并且不能使用明文密码

对于以上解决方案,我们似乎给模型带来了太多的问题。对于最后一种方案,我们必须从以下解决办法中选择一种:

  • 在Tenant中处理对密码的加密,然后将加密后的密码传给User。这种方法违背了单一职责原则

  • 由于一个User必须保证对密码的加密,它可能已经知道了一些加密信息。如果这样,我们可在User上创建一个方法,该方法对明文密码进行认证。但这种方式下,认证过程变成了Tenant的门面(Facade),而实际的认证功能全在User。另外,User的认证方法必须

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值