0% completed
Let's consider a simple application that manages user profiles. In this application, you can create a new user (command), update their email (command), and view user details (query).
CreateUserCommand
with fields like userId
, name
, and email
.CreateUserCommand
, perform business logic, and persist the changes.User
class).UserProfileDTO.
GetUserProfileQuery
with a userId
.Here is the sample code for the aforementioned components:
public class CreateUserCommand { private String userId; private String name; private String email; // Constructor, Getters, and Setters } public class UpdateUserEmailCommand { private String userId; private String newEmail; // Constructor, Getters, and Setters }
public class CreateUserCommandHandler { private UserRepository userRepository; public CreateUserCommandHandler(UserRepository userRepository) { this.userRepository = userRepository; } public void handle(CreateUserCommand command) { User user = new User(command.getUserId(), command.getName(), command.getEmail()); userRepository.save(user); } } public class UpdateUserEmailCommandHandler { private UserRepository userRepository; public UpdateUserEmailCommandHandler(UserRepository userRepository) { this.userRepository = userRepository; } public void handle(UpdateUserEmailCommand command) { if (!isValidEmail(command.getNewEmail())) { throw new IllegalArgumentException("Invalid email format"); } User user = userRepository.findById(command.getUserId()); if (user != null) { user.setEmail(command.getNewEmail()); userRepository.save(user); } } private boolean isValidEmail(String email) { // Simple email validation logic return email != null && email.contains("@"); } }
public class User { private String id; private String name; private String email; // Constructor, Getters, and Setters }
public interface UserRepository { void save(User user); User findById(String id); } public class UserRepositoryImpl implements UserRepository { // Implementation of save and findById methods }
public class UserProfileDTO { private String id; private String name; private String email; // Constructor, Getters, and Setters }
public class GetUserProfileQuery { private String userId; // Constructor, Getters, and Setters } // Read Email Query public class ReadUserEmailQuery { private String userId; // Constructor, Getters, and Setters }
public class GetUserProfileQueryHandler { private UserRepository userRepository; public GetUserProfileQueryHandler(UserRepository userRepository) { this.userRepository = userRepository; } public UserProfileDTO handle(GetUserProfileQuery query) { User user = userRepository.findById(query.getUserId()); return new UserProfileDTO(user.getId(), user.getName(), user.getEmail()); } } // Read Email Query Handler public class ReadUserEmailQueryHandler { private UserRepository userRepository; public ReadUserEmailQueryHandler(UserRepository userRepository) { this.userRepository = userRepository; } public String handle(ReadUserEmailQuery query) { User user = userRepository.findById(query.getUserId()); return user != null ? user.getEmail() : null; } }
public interface CommandBus { void dispatch(CreateUserCommand command); } public class SimpleCommandBus implements CommandBus { private CreateUserCommandHandler handler; public SimpleCommandBus(CreateUserCommandHandler handler) { this.handler = handler; } @Override public void dispatch(CreateUserCommand command) { handler.handle(command); } }
public interface QueryBus { UserProfileDTO dispatch(GetUserProfileQuery query); } public class SimpleQueryBus implements QueryBus { private GetUserProfileQueryHandler handler; public SimpleQueryBus(GetUserProfileQueryHandler handler) { this.handler = handler; } @Override public UserProfileDTO dispatch(GetUserProfileQuery query) { return handler.handle(query); } }
public interface EventStore { void storeEvent(UserEvent event); } public class SimpleEventStore implements EventStore { private List<UserEvent> events = new ArrayList<>(); @Override public void storeEvent(UserEvent event) { events.add(event); } }
This example includes a basic implementation of a command bus, query bus, and a simplified event store. In a full-fledged application, an event store would be used for event sourcing, which is often paired with CQRS. The event store captures changes as a series of events, which can be replayed to rebuild the state of an entity.
.....
.....
.....