1

Basically, my app will work just like stackoverflow, where you login and post something, other people come and interact.

Thinking on DDD terms, and trying to avoid an anemic model, i'm now faced with this decision: Should my User entity holds the knowledge needed to create any post update+delete+retrieve his posts or I should fall back to old patterns where i have a "posts business service" that will get a UserDTO reference, a PostDTO and do everything?

Details:
-I believe that i will need some kind of posts services, because the main page will need to lists all posts, and admin users will be able to delete any post...
-Ideally, only the User entity (and others that inherit from it) should be able to create Posts
-I don't know precisely how I will handle authorization (think block spammers and others)
-Perhaps this should be a domain service triggered by User.CreatePost(postDTO)?

Leonardo
  • 10,737
  • 10
  • 62
  • 155

1 Answers1

5

DDD or CRUD?

Just wanted to call out one part of your question:

create any post update+delete+retrieve

This reveals that perhaps DDD isn't the right answer for this system. Any system where the core requirements are to Create, Read, Update, Delete is not calling out for a DDD approach. In fact, DDD could hamper your successful implementation - a basic CRUD system is likely to make your life a lot easier.

DDD would be when you want to think of things in terms of domain language - users don't "Create Posts", they "Ask Questions" or "Answer Questions". Administrators don't "Delete Posts" they "Archive Posts".

The technical implementation of "Asking a Question" may finally result in a database record getting "Created", but the goal is to push that right down to the persistence layer and have your domain implemented fully in terms of domain "Ubiquitious Language".

Explicit Role Approach

Assuming you are proceeding with DDD, one pattern I have used that is helpful when considering this kind of situation is to avoid the very abstract User entity when considering your core domains of questions and answers.

A User entity is fine for an Identity management bounded context, where you are tracking authentication/sign in details. But once you investigate your core domains, typically the user is more concrete and specific than a general User as they are engaging with the system under a specific role. e.g. you are considering users who are asking and answering questions. Perhaps you will also have users who are moderators, or users who are administrators.

Each of those types of users will carry out different types of activities. So, sometimes it's helpful to model each of those roles explicitly - e.g. a Poster entity, a Moderator entity and an Administrator entity.

You could have Poster.AskQuestion, Poster.AnswerQuestion, Moderator.Moderate etc.

I stress sometimes because very often, the user's role doesn't need to be embodied in the model - the role is just part of the access control/authorization layer, and the model can operate under the assumption that the current user is authorized.

e.g. perhaps the key entity in your case is a MessageBoard which has a MessageBoard.AddPost method.

In your case, however, it might be that the user associated with the post is a core part of the domain - perhaps you will be driving other behavior on the user as part of their question and answering habits, e.g. changing their status, or adding badges or something similar.

Chris Simon
  • 6,185
  • 1
  • 22
  • 31
  • first of all, I over-simplified with the CRUD part... second: different entities that represents users sounds counter-intuitive... i think that posters, moderators and admins are basically users that can perform different actions. But it does make sense to map the method `PromoteToModerator(poster)` only to the admin, and not to a generic IUser and throw not authorized exception... third:I don't think `messageBoard.AddPost` is the correct approach because i think that the user "pins" a post to a board and not the other way around (a board ties a post to a user)... right? – Leonardo Jun 13 '17 at 11:42
  • interestingly http://blog.sapiensworks.com/post/2016/07/14/DDD-Aggregate-Decoded-3 states that AR are roles, which fits neatly with your approach... – Leonardo Jun 13 '17 at 12:01
  • I think that blog post is using the word 'role' with a different connotation to my answer. They are talking about how the purpose of an AR is to carry out a function (i.e. has a role to play in the system) - to justify the fact that in this case, their AR has no state, and is able to be implemented as a pure function, not a class. – Chris Simon Jun 13 '17 at 23:12
  • 2
    In my answer I was more talking about explicitly modelling the different roles that individual users could play "Posters, Moderators and Admins are basically users that can perform different actions" Exactly - modelling them in different classes helps you co-locate the functionality associated with the actions they can perform - rather than ending up with a massive `User` class that can do everything. If an actual person is both a Poster and a Moderator, then they would have an instance of each of those other classes. – Chris Simon Jun 13 '17 at 23:12