领域服务

模型中的领域服务表示一个无状态的操作,他用于实现特定于某个领域的任务。 当领域中某个操作过程或转化过程不是实体或值对象的职责时,我们便应该将该操作放在一个单独的元素中,即领域服务。同时务必保持该领域服务与通用语言是一致的,并且保证它是无状态的。

领域服务的特征

  • 它代表领域概念。
  • 它与通用语言保存一致,其中包括命名和内部逻辑。
  • 它无状态。
  • 领域服务与聚合在同一包中。

何时使用领域服务

如果某操作不适合放在聚合和值对象上时,最好的方式便是将其建模成领域服务。

为避免贫血模型,在封装领域逻辑时,考虑设计要素的顺序为:

Value Object -> Entity -> Domain Service

只有满足如下三个特征的领域行为才应该放到领域服务中

  • 领域行为需要多个领域实体参与协作
  • 领域行为与状态无关
  • 领域行为需要与外部资源(尤其是DB)协作

代码示例

领域服务的执行一般会涉及实体或值对象,在其基础之上将行为封装成业务概念。

比较常见的就是银行转账,首先银行转账具有明显的领域概念,其次,由于同时涉及两个账号,该行为放在账号聚合中不太合适。因此,可以将其建模成领域服务。

public class Account extends JpaAggregate {
    private Long totalAmount;

    public void checkBalance(Long amount) {
        if (amount > this.totalAmount){
            throw new IllegalArgumentException("余额不足");
        }
    }


    public void reduce(Long amount) {
        this.totalAmount = this.totalAmount - amount;
    }

    public void increase(Long amount) {
        this.totalAmount = this.totalAmount + amount;
    }

}

Account 提供余额检测、扣除和添加等基本功能。

public class TransferService implements DomainService {

    public void transfer(Account from, Account to, Long amount){
        from.checkBalance(amount);
        from.reduce(amount);
        to.increase(amount);
    }
}

TransferService 按照业务规则,指定转账流程。

TransferService 明确定义了一个存在于通用语言的一个领域概念。领域服务存在于领域模型中,包含重要的业务规则。

results matching ""

    No results matching ""