2011-09-05 52 views
2

有时,我编码的某些服务需要另一项服务实现的功能。例如,在一次交易后,在编写返回某个ID的用户购买的产品的服务时,我需要购买产品后用户帐户的余额,因此我调用另一个服务来获取数据。在域驱动设计中,服务可以调用其他服务吗?

我可以看到一些替代方案:

  1. 这是很好的做到这一点,你的代码重用。

  2. 服务应该访问自己的回购协议,为他们的行动

  3. 服务应相互隔离检索数据,只涉及到单个域。在我的例子,我应该有另一层,也许是的ViewFactory,调用服务来获取相关数据

什么是对这个问题的普遍接受的准则?

回答

4

是你对Domain Services的问题,而不是应用程序或基础设施服务?如果是这样,DDD没有关于隔离域服务的具体指导。使用您的判断并观察SOLID违规行为。此外,还要注意该域中服务往往滥用,这是有道理的把more logic into Entities

服务应该是明智的,而不是用来允许剥离实体和他们的所有行为值对象。

+0

对不起,延迟回复,是的,这是关于域名服务。 – Extrakun

1

您可以...如果它适合您的特定域环境并且特别适合您的用例。

如果您有几个可能跨越多个聚合根及其服务的用例,您可能需要使用内部应用程序服务或Domain EventHandler来保持DRY原则不变。

但我觉得你不想使用你的UserRepository在你当前的服务中加载用户,因为你觉得它应该关注它的上下文。

我的经验是服务方法粒度差异很大。如果您的服务仅针对一个(或少数)存储库,那么我认为您的粒度很好 - 这意味着您有SaveOrder,LoadOrder,DeleteOrder,LoadUser等...

大粒度更面向用例并尝试以将用例与服务方法(或两个)相匹配。但是OrderService可能具有诸如GetUserPurchaseHistory()

这样的方法返回具有帐户余额的产品在响应DTO对象中。如果您不想使用DTO,您可能需要两个服务电话两个都返回产品和用户帐户余额。 但请记住,应用程序服务层的主要任务是为应用程序客户端及其需求提供服务。如果你不敢让你的粒度更大,你可以将域逻辑推送到code-behind/controller/presenter/webservices。然后,你已经强制了以正确的顺序调用应用程序服务方法的知识给你的客户。

我在某些项目中成功地使用了复杂对话框中的DTO对象,该对象需要跨越多个聚合的数据。这会让GUI人员更容易,而服务API更加面向流程。是的...我为我的服务注入了我需要的几个存储库。我有几个共享存储库的服务(没有严格的1对1关系)。对于不太复杂的用例,我不使用DTO。 DTO在应用程序维护期间为您提供开销和成本时间以及复杂性。虽然它可以提供抗腐蚀层,但很少有人能够获得这种好处。

我希望你明白你可以走的不同方式和利弊。 只是我对你的“十字路口”的看法......

相关问题