深入实践DDD:以DSL驱动复杂软件开发
上QQ阅读APP看书,第一时间看更新

1.3.7 服务

系统中有一些行为是不适合“归属于”哪个对象的,DDD建议把这样的行为定义为服务(Service)。或者说,当有一个操作需要修改多个聚合实例的状态时,这个操作就很有可能应该被定义为服务。

“服务”这个名词在软件开发过程中实在是被用“滥”了。当需要与其他“服务”进行区分时,会称这里所说的“服务”为“领域服务”。

举个例子,我们开发一个账务系统的时候,可能需要支持转账功能。所谓的转账,就是在一个账目(Account)上扣减一定金额的钱,在另外一个账目上增加相应金额的钱。

那么这个转账行为作为账目的一个方法来定义是不是合适呢?如果是作为账目的方法,那么它是应该这样定义(Java代码):


public class Account {
    public void transferFrom(Account sourceAccount, Money amount) {
        //…
    }
}

还是应该这样定义:


public class Account {
    public void transferTo(Account destinationAccount, Money amount) {
        //…
    }
}

我相信,上面两种做法都会引起(不必要的)争议。何不按如下形式定义一个转账服务呢(Java代码):


public interface TransferService {
    void transfer(Account sourceAccount, Account destinationAccount, Money amount);
}

对于这个转账服务来说,它要改变的是两个Account聚合实例的状态,虽然这两个实例的类型都是Account,但是仍然属于所谓的“跨聚合(实例)”的操作,在这种情况下,将其定义为服务比较合适。

在DDD中,还有其他Repository(存储库)、Factory(工厂)等战术层面的概念,建议读者自行阅读DDD相关图书或者到Google上查询资料。