有人能举例说明域服务和应用程序服务之间的区别吗?而且,如果一个服务是一个域服务,我是否会将该服务的实际实现放在域程序集中,如果是的话,我是否也会将存储库注入到该域服务中?一些信息会很有帮助。
当前回答
Domain Services : Methods that don’t really fit on a single entity or require access to the repository are contained within domain services. The domain service layer can also contain domain logic of its own and is as much part of the domain model as entities and value objects. Application Services : The Application service is a thin layer that sits above the domain model and coordinates the application activity. It does not contain business logic and does not hold the state of any entities; however, it can store the state of a business workflow transaction. You use an Application service to provide an API into the domain model using the Request-Reply messaging pattern.
米勒特,C(2010)。专业的ASP。NET设计模式。威利出版。92。
其他回答
域服务:表示不属于任何聚合根的业务逻辑的服务。
You have 2 Aggregate: Product which contains name and price. Purchase which contains purchase date, list of products ordered with quantity and product price at that time, and payment method. Checkout is not part of either of these two models and is concept in your business. Checkout can be created as a Domain Service which fetches all product and compute the total price, pay the total by calling another Domain Service PaymentService with an implementation part of Infrastructure, and convert it into Purchase.
应用程序服务:“编排”或执行域方法的服务。这可以像你的控制器一样简单。
这是你经常做的事情:
public String createProduct(...some attributes) {
if (productRepo.getByName(name) != null) {
throw new Exception();
}
productId = productRepository.nextIdentity();
product = new Product(productId, ...some attributes);
productRepository.save(product);
return productId.value();
// or Product itself
// or just void if you dont care about result
}
public void renameProduct(productId, newName) {
product = productRepo.getById(productId);
product.rename(newName);
productRepo.save(product);
}
您可以在这里进行验证,例如检查Product是否惟一。除非产品是唯一的,否则它应该是域服务的一部分,可能被称为UniqueProductChecker,因为它不能是产品类的一部分,它与多个聚合进行交互。
下面是DDD项目的完整示例:https://github.com/VaughnVernon/IDDD_Samples
你可以找到很多应用程序服务和一些域服务的例子
帮助我理解应用程序服务和域服务之间区别的最好的资源是Eric Evans的cargo示例的java实现,可以在这里找到。如果你下载了它,你可以检查RoutingService(域服务)和BookingService, CargoInspectionService(应用服务)的内部结构。
我顿悟的时刻是由两件事引发的:
阅读上述链接中对服务的描述,更准确地说是这句话:
域服务用通用语言和表示 域类型,即方法参数和返回值为 正确的域类。
阅读这篇博文,尤其是这一部分:
我发现区分苹果和橘子有很大帮助的是 从应用程序工作流的角度考虑。所有关于 应用程序工作流通常以应用程序服务结束 考虑到应用层,而来自领域的概念 这似乎不适合模型对象最终形成一个或多个 域服务。
Domain Services : Methods that don’t really fit on a single entity or require access to the repository are contained within domain services. The domain service layer can also contain domain logic of its own and is as much part of the domain model as entities and value objects. Application Services : The Application service is a thin layer that sits above the domain model and coordinates the application activity. It does not contain business logic and does not hold the state of any entities; however, it can store the state of a business workflow transaction. You use an Application service to provide an API into the domain model using the Request-Reply messaging pattern.
米勒特,C(2010)。专业的ASP。NET设计模式。威利出版。92。
服务有三种类型:域服务、应用服务和基础设施服务。
域服务:封装 业务逻辑并不自然 适合于域对象,并且不是典型的CRUD操作——那些属于存储库。 应用程序服务:由 外部消费者与你交谈 系统(考虑Web服务)。如果使用者需要访问CRUD操作,它们将在这里暴露。 基础设施服务:习惯 抽象的技术问题(例如: MSMQ,电子邮件提供商等)。
把域服务和域对象放在一起是明智的——它们都关注域逻辑。是的,您可以将存储库注入到服务中。
应用程序服务通常会同时使用域服务和存储库来处理外部请求。
从红皮书(实现领域驱动设计,由Vaughn Vernon)中,我是这样理解这些概念的:
域对象(实体和值对象)封装了(子)域所需的行为,使之自然、有表现力和可理解。
域服务封装了这些不适合单个域对象的行为。例如,一个图书馆可以通过域服务将图书借给客户端(带有相应的库存更改)。
应用程序服务处理用例流,包括域之上所需的任何附加关注点。它经常通过API公开这样的方法,供外部客户端使用。基于前面的例子,我们的应用程序服务可能会公开一个方法LendBookToClient(Guid bookGuid, Guid clientGuid):
Retrieves the Client. Confirms its permissions. (Note how we have kept our domain model free of security / user management concerns. Such pollution could lead to many problems. Instead, we fulfill this technical requirement here, in our application service.) Retrieves the Book. Calls the domain service (passing the Client and Book) to handle the actual domain logic of lending the book to the client. For instance, I imagine that confirming the book's availability is definitely part of the domain logic.
应用程序服务通常应该具有非常简单的流程。复杂的应用程序服务流通常表明域逻辑已经泄漏出域。
正如您所希望看到的,领域模型以这种方式保持非常干净,并且易于理解并与领域专家讨论,因为它只包含它自己的实际业务关注点。另一方面,应用程序流也更容易管理,因为它消除了领域问题,变得简洁明了。