Implement the RegistrationManagement class

With all of the test methods we created in the preceding section, you probably already have an idea of how RegistrationManagement will look, and here it is:

...
@Component
public class RegistrationService {

private UserRepository repository;
private PasswordEncryptor passwordEncryptor;

public RegistrationManagement(UserRepository repository, PasswordEncryptor passwordEncryptor) {
this.repository = repository;
this.passwordEncryptor = passwordEncryptor;
}

public User register(String username, String emailAddress, String password) throws RegistrationException {
User existingUser = repository.findByUsername(username);
if (existingUser != null) {
throw new UsernameExistsException();
}

existingUser =
repository.findByEmailAddress(emailAddress.toLowerCase());
if (existingUser != null) {
throw new EmailAddressExistsException();
}

String encryptedPassword = passwordEncryptor.encrypt(password);
User newUser = User.create(
username, emailAddress.toLowerCase(), encryptedPassword);
repository.save(newUser);
return newUser;
}
}

As you can see, this domain service is quite straightforward. Some might doubt the existence of this RegistrationManagement class and argue that this is over-design because this registration logic can be put inside the register() method of UserServiceImpl so that the effort of creating RegistrationManagement can be saved. Others might even prefer to move this registration logic inside RegistrationController so that the code can be much simpler. If we look at these two alternatives from a simplicity perspective, there is no doubt that they are both simpler. However, if we look at this from the extensibility and maintainability point of view, the use of RegistrationManagement is better because it encapsulates the necessary business rules so that its clients, who invoke its register() method, don't need to care about those rules. And, in the future, when we need to add more rules to the registration process, we just need to modify RegistrationManagement.

Some might prefer to declare RegistrationManagement as an interface and then use RegistrationManagementImpl, for example, to implement the actual logic. For Application Services, which set up the boundary between the Application Core and its clients, using an interface is preferred because we don't want Controller to directly reference the actual implementation, which gives us a narrow space to evolve the implementation. For Domain Services such as RegistrationManagement, there is no need to declare a boundary inside the Application Core. The only time it would make sense to use an interface for Domain Services is when you need to apply the Strategy design pattern, in which case there will be multiple implementations of the same interface and the choice of implementation depends on the strategy that is needed.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.137.12