TypeScript 中关于 DDD 的故事继续,本期将介绍第一个无状态模式 —— 域服务。
我没有关于命名代码结构的官方统计数据,但让我们诚实点 —— 我们是开发人员,我们给类命名......几乎很好,大部分很糟糕。在大多数情况下,我们提供一些几乎唯一的名字,并附加一些后缀。
名称可以不同:用户、帐户、注册......选项是无限的。但是,后缀是有限的,在大多数情况下,它们是:实体、存储库、工厂、服务......
是的,服务!我相信这是最常见的后缀,无论我们使用DDD或任何其他模式都无关紧要。在许多情况下,Service只是用于我们无法更好地命名的任何东西。
服务可能是DDD模式中被误用最多的模式之一。对域服务的误解来自于许多不同的Web框架,在这些框架中,服务就是一切。
但是域服务的实际目的是什么?它与我们放在应用层上的其他服务有什么区别?
让我们开始吧。
无状态的
事实一:Domain Service不允许持有状态,也不允许包含任何具有状态的字段,包括间接的。
事实二:这可能是所有战术DDD模式中最重要的规则。
这条规则可能很明显,但不幸的是,它并不是,取决于每个开发人员的背景,他们中的一些人有在Web开发中使用语言的经验,这些语言为每个请求运行独立的进程。
在这种情况下,服务是否包含状态并不重要,但是当你使用 NodeJS 时,你可能会为整个应用程序使用单个 Domain Service 实例。
因此,你可以想象如果许多不同的客户访问内存中的相同值会发生什么。
// Entity keeps state like Person Entity, Wallet Value Objects etc
class Account {
private id: number;
private person: Person;
private wallets: Wallet[];
// some business logic
}
// Value Object keeps state like Currency Entity, Amount primitive type etc
class Money {
private amount: number;
private currency: Currency;
// some business logic
}
// Domain Service depends only on other stateless constructs like:
// other Services, Repositories, Factories, objects that represent app configuration
class DefaultExchangeRateService {
private repository: ExchangeRateRepository
private useForceRefresh: boolean;
// some business logic
}
class TransactionService {