Reputation: 1
I'm creating a backend application and I'm trying to implement the Domain Driven Design. However, I had a question regarding my data structure that I intend to clarify.
Users |
---|
Id (PK 🔑) |
First Name |
Last Name |
Password |
Customers Profile |
---|
User Id (PK / FK 🔑) |
Height |
Weight |
Personal Trainers Profile |
---|
User Id (PK / FK 🔑) |
Specialties |
Taking into account the database represented above, I have some doubts on how to structure the Controllers, Services and Repositories of my application.
Let's imagine, that I want to update a Customer Profile and their User:
And to update their respective User on Users table? Should the Customer Service call an update method from the User Service? Or should the Customer Service call the User Repository directly?
I'm very confused, not knowing if it's correct, services know about other services, or services know repositories that theoretically belong to other services.
I will be very gratefully if someone could help me clarifying my doubts 🙂
Upvotes: 0
Views: 440
Reputation: 181
I think the Database structure can be improved.
Rather than naming the table as Customer Profile and Personal Trainer Profile, name it as Customers and Personal Trainers.
As A Customer
is a User
&
A Personal Trainer
is a user
Users |
---|
Id (PK 🔑) |
First Name |
Last Name |
Password |
Customers |
---|
Id (PK 🔑) |
User Id (FK 🔑) |
Height |
Weight |
Personal Trainers |
---|
Id (PK 🔑) |
User Id (FK 🔑) |
Specialties |
The Aggregate Roots are Customers & PersonalTrainers.
Now the Controllers and Services will be for Customers & personal trainers.
And any update to fields for users table for customers will be done via Customer Controller.
The class definition
public class Customers extends Users
&
public class PersonalTrainers extends Users
Upvotes: 2
Reputation: 13246
Aggregates are independent objects that ensure consistency within the aggregate. A User
represents a specific concept and a CustomerProfile
another. The CustomerProfile
should rather have its own Id (not necessarily UserId
). Nothing stops you from modelling it as you have but keeping state changes on the two aggregate separate is going to make your life a lot easier.
That being said, whenever I do find that I have application services that make use of one another in some way I apply the good old "All problems in computer science can be solved by another level of indirection". I take the common bits and make a Task
of sorts and use that in each.
Upvotes: 0
Reputation: 732
Sorry if I'll be a bit 'crude', but in your approach there's no real clue about DDD. I mean: Controllers, Services and Repositories are the 'the facto' way to develop an application with Spring. But this is not really DDD. To implement it with DDD you have to forget the database, focus on the entities of the domain, identify their functionalities and start to think how to translate this into code.
With this preface, I can say you that also within this 'the facto' approach is possible to adopt a DDD, at the price to rethink all the process that produces the code.
Hence, in your model, I would do something like this:
Once you know your entities, or at least you start to identify them and some functions, you can think about the code. Here you can choose between several architectures: clean, ports & adapters, onion, 3-Layers architecture (the default and classic approach with Spring: controllers, services and repositories with entities). My personal approach is more or less what is described here.
I would suggest you to search and read a lot about how to do the things. There's no silver bullet, unfortunately: sometimes the domain is really simple and the extra overhead of a DDD and an 'unsual' architecture are totally useless; sometimes the domain is complex and big, hence a DDD approach with a more refined architecture are a much better choice.
Finally, to give you a concrete answer to work on your case, after identifying the entities and their functions I would put the model that you have produced into a domain package. Here I would also define the Repository interfaces, that you use to persist the entities (but you'll implement later). Once you have this, you can develop the services, where you put all the things together using what you have into the domain. I would put this code into an application package (but, remember, it's not a law: if you think is better, place them in a different place, or with a different name - take a look here, I really like this approach). Finally, I would start to implement the code of the infrastructure layer, where all the interfaces defined into the domain and the application layers will be implemented. Here I would put also the Controllers.
Remember: this approach allows only connections in one direction (domain -> application -> infrastructure), but never the opposite.
Finally, if you think about how to manage the domain entities with some ORM frameworks, I would suggest you to read this links: domain vs persistence model; stackoverflow question about this; domain and persistence separated.
Upvotes: 0