Good Code
The good version gives business behavior a service boundary. Persistence and email are dependencies, not hidden work inside a controller.
Lesson 10
Keep controllers, services, repositories, and packages focused so each layer owns one kind of decision.
package dev.review.user;
public final class UserService {
private final UserRepository users;
private final WelcomeEmail welcomeEmail;
public UserService(UserRepository users, WelcomeEmail welcomeEmail) {
this.users = users;
this.welcomeEmail = welcomeEmail;
}
public UserProfile register(CreateUserCommand command) {
User user = users.save(User.create(command.email(), command.displayName()));
welcomeEmail.sendTo(user);
return UserProfile.from(user);
}
}public class UserController {
public ResponseEntity<?> register(HttpServletRequest request) throws SQLException {
String email = request.getParameter("email");
Connection connection = DriverManager.getConnection(databaseUrl);
Statement statement = connection.createStatement();
statement.executeUpdate("insert into users(email) values('" + email + "')");
mailer.send(email, "Welcome");
return ResponseEntity.ok().build();
}
}The good version gives business behavior a service boundary. Persistence and email are dependencies, not hidden work inside a controller.
The bad version mixes request parsing, SQL construction, database connection management, email, and HTTP response code in one class.