Reputation: 6300
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 ?
Upvotes: 0
Views: 229
Reputation: 43728
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
.
Upvotes: 1
Reputation: 23
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.
Upvotes: 0