Piszę sobie na boku projekt, w którym postanowiłem z początku nie skupiać się za bardzo na architekturze, wzorcach, clean code, itp, chciałem po prostu dowieźć jak najszybciej założone MVP. Skończyło się na tym, ze backend dojechał faktycznie bardzo szybko, jednak póki kolega dłubie przy froncie i ja nie mam co robić, chciałem trochę poprawić to co napisałem.
No i jedna klasa szczególnie mi się nie podobna, aczkolwiek brak mi pomysłów jaki wzorzec tu zastosować, czy da się w ogóle ją jakoś zdekomponować, podzielić na mniejsze klasy?
Jest ona odpowiedzialna za tworzenie użytkownika, czyli musi:
-przeprowadzić walidację
-zapisać użyktownika na bazie
-wygenerować i zapisać na bazie token aktywacyjny
-wysłać maila z tym tokenem
Pierwsze co się rzuca to Single Responsible Principle które tutaj jest łamane... Z resztą wrzucam sam kod i z chęcią usłyszę wszelką krytykę i sugestie jak to poprawić
@Service
@RequiredArgsConstructor
public class UserCreator {
private final UserRepository userRepository;
private final ActivationTokenRepository tokenRepository;
private final EmailSender emailSender;
private final UserValidator userValidator;
private final PasswordEncoder encoder;
public MessageDto registerUser(RegisterUserDto registerUserDto) throws ApplicationException {
userValidator.validate(registerUserDto);
var user = saveUser(registerUserDto);
var token = generateToken(user.getUsername());
sendEmail(user.getEmail(), user.getUsername(), token.getId());
return new MessageDto("User '" + registerUserDto.getUsername() + "' successfully created. Please check your email to activate your account");
}
private User saveUser(RegisterUserDto registerUserDto) {
var user = buildUser(registerUserDto);
return userRepository.save(user);
}
private ActivationToken generateToken(String username) {
var token = buildToken(username);
return tokenRepository.save(token);
}
private void sendEmail(String receiverAddress, String username, String tokenID) {
var activationEmail = buildEmail(receiverAddress, username, tokenID);
emailSender.sendEmail(activationEmail);
}
private User buildUser(RegisterUserDto registerUserDto) {
return User.builder()
.username(registerUserDto.getUsername())
.password(encoder.encode(registerUserDto.getPassword()))
.email(registerUserDto.getEmail())
.active(false)
.roles(Set.of("USER"))
.build();
}
private UserActivationEmailDto buildEmail(String receiverAddress, String username, String tokenID) {
return UserActivationEmailDto.builder()
.subject("Aktywacja konta na xxx.pl")
.receiver(receiverAddress)
.token(tokenID)
.username(username)
.build();
}
private ActivationToken buildToken(String username) {
return ActivationToken.builder()
.username(username)
.expirationDateTime(LocalDateTime.now().plusHours(1))
.activated(false)
.build();
}
}