Domain Drive Design, how to implement this type of rule

203 Views Asked by At

I try to practice DDD but I have a doubt about this type of rules that I wrote bellow:

class UserAggregator under domain layer.

public class UserAggregator{
private UUID userId;
private String userName;
private String country;
//getter

boolean isUserNamePatternCorrect(){
  return this.userName.startsWith("TOTO"); 
}
}

Repository interface under domain layer.

public interface UserRepository {//User Table
     public UserAggregator findUser(UUID id);
     public void deleteUser(UserAggregator userToARchive);
}

public interface ArchiveUserRepository { //ArchiveUser Table
     public archiveUser(UUID id);
}

the UserRepository/ArchiveUserRepository are implemented under infrastructure layer using spring data.

Service under infrastructure layer.

public  class MyService {

@Autowired
UserRepository userRepo;

@Autowired
ArchiveUserRepository archiveUserRepo;

public void updateUserName(UUID userId){

       UserAggregator userAgg = userRepo.findUser(userId);
       if(Objects.nonNull(userAgg)){
         boolean isCorrect = userAgg.isUserNamePatternCorrect();
        if(!isCorrect){//-----------------------------1
            userRepo.deleteUser(userAgg);//-----------2
            archiveUserRepo.archiveUser(userAgg);//---3
           }
       }
//....
}
}

my management rule says, if the userName does not match the pattern then archive the user into archive table and remove it from user table.

as you notice, the rule (from //1 to //3) is written in the service class and not into my agregator!

Is this correct ? or how to manage this ?

2

There are 2 best solutions below

0
On

As it seems to be an infrastructure rule on how to behave in that particular case of having an incorrect username, I don't see any problem on your code. The responsabilities belong to the repositories IMHO, so I think that this approach is more than correct.

0
On

First of all, it's not "Aggregator", it's "Aggregate" and second don't actually put the "Aggregate" suffix, it doesn't bring any value and goes against a business-driven language (Ubiquitous Language).

my management rule says, if the userName does not match the pattern then archive the user into archive table and remove it from user table

Well, I think the problem is that this is not a business rule at all, it's a technical specification. Why would business experts care about database tables? DDD is helpful to model & describe rules in an infrastructure-agnostic way, so it won't be very helpful to model technical specifications.

There's a few ways to retain the technical specification while eliminating the infrastructure pollution though, for instance the repository could make the storage decision based on an archived state.

class User {
   boolean archived;

   void changeUserName(String userName) {
       this.userName = userName;

       if (!isUserNamePatternCorrect()) {
           this.archived = true;
       }
   }
}

class UserRepository {
    save(User user) {
        if (user.archived) ...
    }
}

If you need to be more technically explicit then you could perhaps capture the logic in a domain service and use a similar approach to what you have or perhaps even dispatch a domain event such as UsernameChanged and have it handled by a UserArchivingPolicy.