面向服务的体系结构&领域驱动设计

时间:2010-03-18 03:59:37

标签: domain-driven-design design-patterns soa

我总是以SOA类型的方式开发代码。今年我一直在努力做更多的DDD,但我一直觉得我没有得到它。在工作中,我们的系统是负载平衡的,并且设计为不具有状态。架构是:

网站

===物理层==

主要服务

==物理层==

服务器1 /服务2 /服务3 /服务4

只有服务器1,服务2,服务3和服务4可以与数据库通信,主服务根据订购的产品调用正确的服务。每个物理层也都是负载平衡的。

现在,当我开发一项新服务时,我会尝试在该服务中考虑DDD,即使它确实不适合它。

我使用了很好的DDD原则,如实体,价值类型,存储库,聚合,工厂等。

我甚至尝试使用ORM,但他们似乎并不适合无状态架构。我知道有很多方法,例如使用IStatelessSession而不是NHibernate的ISession。但是,ORM只是觉得它们不适合无状态架构。

我注意到我真的只使用了DDD教给我的一些概念和模式,但整体架构仍然是SOA。

我开始认为DDD不适合大型系统,但我认为其中一些模式和概念适合大型系统。

就像我说的那样,也许我只是没有抓住DDD或者我可能不在分析我的设计?也许通过使用DDD告诉我的模式和概念我使用DDD?不确定这篇文章是否真的存在问题,但在尝试确定DDD在整个系统中的适用位置以及它的真实可扩展性时,我有更多的想法。事实是,我认为我甚至不知道DDD是什么?

4 个答案:

答案 0 :(得分:23)

我认为一个常见的误解是SOA和DDD是两种相互冲突的风格。

IMO,它们是两个共同发挥作用的概念; 您可以创建一个封装域概念的域模型,并通过服务将入口点公开到该模型中。

我也看不出ORM和服务有什么问题,你可以轻松地使用每次服务调用的会话/ uow。 只需将您的服务操作建模为原子域命令。

一个天真的例子:

[WebMethod]
void RenameCustomer(int customerId,string newName)
{
    using(var uow = UoW.Begin())
    {
        var customerRepo = new CustomerRepo(uow);
        var customer = customerRepo.FindById(customerId);
        customer.Rename(newName);
        uow.Commit();
    }
}

您遇到的问题可能是您创建了像“UpdateOrder”这样的服务,它接受订单实体并尝试在新会话中更新它?

我尽量避免使用这种服务,而是将这些服务分解为更小的原子命令。

每个命令都可以作为操作公开,或者您可以使用单个服务操作接收命令组,然后将这些命令委托给命令处理程序。

IMO,这样你可以更好地揭露你的意图。

答案 1 :(得分:8)

域驱动设计最重要的事情是全局的想法:

  • 无所不在的语言,
  • 战略决策,通过在核心领域工作来增加价值(并使自己与其他讨厌的系统隔离),
  • 通过将基础架构与业务逻辑分离来实现可测试,灵活设计的方法。

这些广泛适用,是最有价值的作品。

有很多关于工厂,服务,存储库,聚合等的设计模式的东西,我把它作为一个有经验的开发人员给另一个人的建议,而不是作为福音,因为它的大部分都可以根据您正在使用的语言和框架。 imho他们往往被过分强调,因为像我们这样的程序员是以细节为导向的,我们对这种东西着迷。那里也有宝贵的东西,但需要保持透视。因此,有些内容可能与您无关,或者在您使用它时可能会对您产生影响。

所以我想说这不是一个清单,你可以确保你使用所有的模式,这是一个关注的问题,看看这会如何改变你开发软件的方法。如果你从模式中汲取一些好的技巧,那也很棒。

特别是关于SOA的事情,我开发了将所有状态推迟到数据库的应用程序,这些数据库使用了持久性无知的域对象。为必须模拟daos和反馈东西的服务编写测试是苦差事,我可以在域对象中添加的逻辑越少,我在服务中的模拟就越少,所以我倾向于更喜欢这种方法。

答案 2 :(得分:7)

DDD引入了一些概念,在构建SOA时实际上会让您感到困惑。

我必须完全同意another answer,即SOA服务公开充当原子命令的操作。我相信一个非常干净的SOA使用消息而不是实体。然后,服务实现将利用域模型来实际执行操作。

然而,DDD中有一个称为“域服务”的概念。这与应用程序服务略有不同。通常,“域服务”是在与域模型的其余部分相同的普遍存在的语言中设计的,并且表示不完全适合实体或值的业务逻辑。

域服务不应与应用程序服务混淆。实际上,可以很好地实现应用服务,使得它使用域服务。毕竟,应用程序服务可以完全封装SOA中的域模型。

答案 3 :(得分:3)

我真的很晚了,但我想在其他人的非常好的答案中添加以下内容。

  • DDD与SOA没有任何冲突。相反,DDD可以帮助您维护更好的面向服务的体系结构。 SOA促进了服务的概念,因此您可以在系统之间定义更好的边界(哦,上下文边界也是DDD概念!)并提高对它们的理解。
  • DDD不是关于应用一组模式(例如存储库,实体等)。 DDD主要是试图对软件进行建模,因此所有概念(即面向对象编程时的类)都直接与业务概念保持一致。

您还应该检查this video(特别是最后5分钟),其中Eric Evans正好讨论了这个主题。

  

我甚至尝试使用ORM,但他们似乎并不适合   无国籍建筑。

我没有任何参考方便支持。但是,你是对的,ORM也不适合DDD。这是因为,他们试图以错误的方式桥接object-relational impedance mismatch。他们强迫软件走向anemic domain model,其中的类最终成为“普通数据持有者”。

  

我开始认为DDD不适合大型系统,但我确实认为   一些模式和概念确实适用于大型系统。

在我上面链接的视频中,您还可以找到Eric解释DDD概念可以在非常大规模的系统中“破解”。例如,想象一下零售系统,其中每个订单都是包含可能数千个订单商品的聚合。如果您想严格按照DDD计算订单的总金额,则必须在内存中加载所有订单项,与利用存储系统相比,这将是非常低效的(例如,使用聪明的SQL语句)。因此,应始终牢记这种权衡,DDD不是银弹。

  

就像我说的,也许我只是没有抓住DDD或者我可能已经结束了   分析我的设计?

对不起,但我不得不再次引用Eric Evans。正如他所说,DDD不是完美主义者,这意味着可能存在理想设计不存在的情况,你可能不得不采用一种解决方案,这在建模方面更糟糕。要了解更多信息,您可以查看this article