如果我完全破坏了DDD概念,请让我知道,但这是我的两难选择。
假设我有以下域模型:
Teacher
IList<Class>
Class
Teacher
IList<Student>
Student
Class
现在,从DDD的角度来看,教师似乎是我的根,事实上,在一个简单的应用程序中,我可以带着她的班级和学生随身携带我的老师,并根据需要采取行动。但是在SOA情况下,假设我已经将我的老师,她的班级和学生拉下来用于显示目的(如dtos),并且她想要添加一名学生。当然,我不会将整个对象图发送到服务器并从数据库中检索域对象,以便我可以添加一个新学生,对吧?
这里的甜蜜点在哪里,还是我完全错过了这条船?
谢谢!
Late Upate:也许我正在回答我自己的问题,但我想一种方法是让我的教师服务有各种学生管理方法(AddStudent,UpdateStudent),这样我的root仍然可以管理所有内容而不是每个服务一个宾语。
答案 0 :(得分:55)
我会说你们都错过了这条船,同时也在正确的轨道上......让我解释一下。
DDD是我们将业务问题的现实编入我们可以映射到计算机程序的解决方案领域的行业的最佳方式。 DDD是一种将真实域抽象为更易于管理且与我们相关的东西的方法,这些都是好事。
您面临的问题是在实现中,过去20 - 30年的主流实现选择是面向对象(OO),在OO中传递对象的核心机制是通过传递对象中的对象的引用记忆空间就像你自己。所以你面临的问题就是大对象图,而这些问题从来都不是真正的问题。
输入服务方向(SO),它会翻转事物,您不再传递对象的引用,而是在服务之间交换消息。消息的大小现在成为一个问题。
如果我们接受实施范式已经改变,我们需要接受我们的一些OO最佳实践/模式不再适用或需要修改。
如果你想进入思维方式,你需要,我相信(我的观点在这里),稍微放开一个富有领域的想法。我将这个新概念称为面向服务的域(SO域)。
在SO-Domain中,域的状态和域的行为在您传递的消息和您使用的服务之间分配。
因此,教师的状态或属性属于TeacherDTO的一部分,但行为是教师服务的一部分。
在OO术语中,这是一个贫血领域,但从某种意义上来说,这并不是一件坏事,因为这会给你一些惊人的灵活性,因为你不再有一件大事,状态可以在多种情境中使用。
您仍然拥有一个有效的域,它只是差异化分区,消息保持状态和服务保持行为。
其余的归结为服务界面设计,所以为了获得教师的课程,你可以拥有像List RetrieveTeacherClasses(teacherIdentifier)这样的东西。添加学生AddStudentToClass(Student,classId)。
有一百万种不同的方法可以找到适合你的方法,但作为一般规则,你应该遵循状态感知范式,这意味着消息将发送服务需要知道的任何状态off,这使服务成为无状态服务,无状态服务意味着可扩展性。
Pratik提到性能,系统范围内的真正性能提升不是通过对象图的大小进行讨论,而是作为解决方案中每个服务独立扩展的能力。
以下是一些关于这些想法的更多链接
答案 1 :(得分:1)
你在考虑表现,但你会感到惊讶。在我的SOA Web服务中,我使用了这样的完整对象图,性能完全在可接受的范围内。我建议使用业务对象和业务网络方法,如SaveTeacher(Teacher t)
,除非出于性能原因绝对需要使用DTO,以及AddStudent(long teacherId, Student student)
等相关的CRUD网络方法
但即使使用后者,您也可以通过在给定teacherId的情况下从持久性存储中加载教师来应用DDD概念,附加学生并将教师保存回持久性存储。
答案 2 :(得分:0)
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);
答案 3 :(得分:-1)
对于SOA,您需要应用程序服务。看看here,找出你的功能应该去哪里。