【问题标题】:Do DDD and SOA really play well together?DDD 和 SOA 真的可以很好地协同工作吗?
【发布时间】:2026-01-27 04:10:01
【问题描述】:

如果我完全破坏了 DDD 的概念,请以非常温和的方式告诉我,但这是我的两难选择。

假设我有以下领域模型:

Teacher
  IList<Class>

Class
  Teacher
  IList<Student>

Student
  Class

现在,从 DDD 的角度来看,老师似乎是我的根,事实上,在一个简单的应用程序中,我可以随身携带老师和她的班级和学生,并根据需要采取行动。但是在 SOA 情况下,假设我出于显示目的(作为 dtos)删除了我的老师、她的班级和学生,并且她想添加一个学生。当然,我不会将整个对象图发送到服务器并从数据库中检索域对象,这样我就可以添加一个新学生,对吧?

这里的最佳位置在哪里,还是我完全错过了这条船?

谢谢!

Late Upate:也许我在回答我自己的问题,但我想一种方法是让我的教师服务有各种学生管理方法(AddStudent、UpdateStudent),这样我的根仍然管理所有内容,而不是每个服务都有一个服务目的。

【问题讨论】:

    标签: domain-driven-design soa


    【解决方案1】:

    Vijay 的意思是用 AddStudent 方法添加一个 TeacherService

    interface ITeacherService
    {
      Teacher GetTeacher (name teacher);
      void AddStudent (Teacher teacher, Student student);
    }
    

    那么你最终会得到如下的结果:

    Student student = new Student ("Bobby Drop Tables;");
    Teacher teacher = teacherService.GetTeacher ("Bob");
    teacherService.AddStudent (teacher, student);
    

    【讨论】:

      【解决方案2】:

      我会说你们都错过了这条船,同时在正确的轨道上......让我解释一下。

      作为一个行业,DDD 是我们将业务问题的现实编码为我们可以映射到计算机程序的解决方案域的最佳方式。 DDD 是一种将真实领域抽象为对我们更易于管理和相关的方法,这些都是好东西。

      您面临的问题是在实现中,过去 20-30 年流行的实现选择是面向对象 (OO),在 OO 中传递对象的核心机制是通过传递对同一对象的引用像你自己一样的记忆空间。因此,您在大型对象图方面面临的问题从来都不是真正的问题。

      进入服务导向 (SO) 翻转事物,您不再传递对对象的引用,而是在服务之间交换消息。消息的大小现在成为一个问题。

      如果我们接受实施范式已经改变,我们需要接受我们的一些 OO 最佳实践/模式不再适用或需要修订。

      如果你想进入 SO 的思维方式,我相信(我的观点)你需要稍微放弃富域的想法。我将这个新概念称为面向服务的域(SO-Domain)。

      在 SO-Domain 中,域的状态和域的行为分为您传递的消息和您使用的服务。

      所以教师的状态或属性是教师DTO的一部分,但行为是教师服务的一部分。

      在 OO 术语中,这是一个贫乏的领域,但从某种意义上说,这并不是一件坏事,因为这给了您一些惊人的灵活性,因为您不再拥有一件大事,状态可以在多种情况下使用。

      您仍然有一个有效的域,它只是进行了差异分区,消息保持状态,服务保持行为。

      剩下的就归结为服务接口设计了,因此要为教师获取课程,您可以使用 List RetrieveTeacherClasses(teacherIdentifier) 之类的东西。添加学生 AddStudentToClass(Student, classId)。

      有一百万种不同的方法可以做到这一点,您会找到适合您的方法,但作为一般规则,您应该遵循状态感知范式,这意味着消息将发送服务需要了解的任何状态关闭,这使得服务是无状态的,无状态服务意味着可扩展性。

      Pratik 提到了性能,系统范围内的真正性能提升不是通过关注对象图的大小来实现的,而是解决方案中每个服务独立扩展的能力。

      这里有一些关于这些想法的更多链接

      Building a SOA

      SOA Design Pattern

      Achieving integrity in a SOA

      Why your SOA should be like a VW Beetle

      SOA explained for your boss

      WCF Service Performance

      【讨论】:

      • 嘿,这个答案太棒了!我正在考虑注册第二个帐户,这样我就可以投票两次了.. ;-) 真的,非常感谢您的解释。
      • 非常自信的答案。清楚地展示了对 SOA 的“架构师”级别的理解。问候。
      • 这很鼓舞人心。谢谢!
      • 我特别喜欢:“我们需要接受我们的一些 OO 最佳实践/模式不再适用或需要修改。”至少对我来说,这鼓励我无视整个“贫血域模型是一种反模式”的论点。此外,我认为应该更频繁地提及域 = 服务 + 消息的整个概念。
      【解决方案3】:

      您正在考虑性能,但您会感到惊讶。在我的 SOA Web 服务中,我使用了如此完整的对象图,并且性能完全在可接受的范围内。我建议使用 SaveTeacher(Teacher t) 之类的业务对象和业务 Web 方法,除非出于性能原因绝对需要使用 DTO 和关联的 CRUD Web 方法,例如 AddStudent(long teacherId, Student student)
      但即使使用后者,您也可以应用 DDD 概念,方法是根据给定的teacherId 从持久存储中加载教师,附加学生并将教师保存回持久存储。

      【讨论】:

        【解决方案4】:

        对于 SOA,您需要应用程序服务。看看here,找出你的功能应该去哪里。

        【讨论】:

        • 并没有真正解决关于 DDD 和 SOA 是否相互正交的问题。
        最近更新 更多