Please let me know, ever so gently, if I am totally mangling the DDD concept, but here is my dilemma.
Let's say I have the following domain model:
Teacher
IList<Class>
Class
Teacher
IList<Student>
Student
Class
Now, from a DDD perspective, it seems like the Teacher is my root, and indeed, in a simple app, I might carry around my Teacher with her classes and students and act on them as needed. But in an SOA situation, let's say I've pulled down my Teacher, her classes and students for display purposes (as dtos), and she wants to add a student. Surely I am not going to send the whole object graph up to the server and retrieve the domain objects from the database just so that I can add a new student, right?
Where is the sweet spot here, or am I totally missing the boat?
Thanks!
Late Upate: Maybe I'm answering my own question, but I guess one approach is to have my Teacher service have various student management methods (AddStudent, UpdateStudent) such that my root is still managing everything instead of having one service per object.
Domain Driven Design (DDD) has recently gained additional popularity, as evidenced by new books, conference talks, and even complete conferences dedicated to it), and lots of trainings – including some by our very own colleagues here at INNOQ.
DDD provides an avenue to facilitate the development of highly cohesive systems through bounded contexts. Microservices is an implementation approach that encourages you to focus your service boundaries on the business domain boundaries.
DDD patterns help you understand the complexity in the domain. For the domain model for each Bounded Context, you identify and define the entities, value objects, and aggregates that model your domain. You build and refine a domain model that is contained within a boundary that defines your context.
Microservices offer some serious advantages over traditional architectures, providing scalability, accessibility, and flexibility. Moreover, this approach keeps developers focused as each microservice is a loosely coupled service with a single idea of accountability.
I would say you are both missing the boat, and at the same time on the right track.... let me explain.
DDD is the best way we know as an industry to codify the reality of a business problem into a solution domain that we can map to a computer program. DDD is a methodology to abstract a real domain into something more manageable and relevant for us, these are good things.
The problem you are facing is in the implementation, the prevailing implementation choice for the last 20-30 years has been object orientation (OO), the core mechanism of passing objects around in OO is by passing references to objects in the same memory space as yourself. So the problems you are facing about large object graphs where never a real problem.
Enter Service orientation (SO) which flips things around, you are not longer passing references to objects, but exchanging messages between services. The size of the message now becomes a concern.
If we accept that the paradigm of implementation has changed, we need to accept that some of our OO best practices/patterns either no longer apply or need revision.
If you want to get into the SO way of thinking, you need to, I believe (my opinion here), let go of the idea of a rich domain slightly. I term this new concept a Service-Orientated-Domain (SO-Domain).
In a SO-Domain the state of the domain and the behavior of the domain is split between the messages you pass and the services you use.
So the state or the attributes of the teacher are part of the TeacherDTO, but the behavioral is part of the teacher service.
In OO terms this is an anemic domain, but in a SO sense it is not such a bad thing as this gives you some amazing flexibility, as you no longer have one big thing, the state can be used in multiple contexts.
You still have a valid domain, it is just partitioned differentially, messages hold state and services hold behavior.
The rest comes down to service interface design, so to get the class for a teacher you could have things like List RetrieveTeacherClasses(teacherIdentifier). To add a student AddStudentToClass(Student, classId).
There are a million different way to do this you will find the one that works for you, but as a general rule you should follow a state-aware paradigm, this means the message will send any state the service needs to be aware off, this enables the service to be stateless, and stateless service mean scalability.
Pratik mentions performance, true performance gains on a system wide scale are not made by fussing over the size of object graphs, but as the ability of every service in the solution to scale independently.
Here are some links to more on these ideas
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
You are thinking about performance, but you will be surprised. In my SOA web services I use such complete object graphs and performance is well within acceptable limits. I would suggest to use business objects and business web methods like SaveTeacher(Teacher t)
unless absolutely required to use DTOs for performance reason and associated CRUD web methods like AddStudent(long teacherId, Student student)
But even if using the later you can apply the DDD concept by loading the teacher from your persistence store given the teacherId, attaching the student and saving the teacher back to persistence store.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With