Created
October 14, 2025 17:37
-
-
Save kaelfeitosa/4efd7a563ef473ea1811a6e808a807d4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.util.ArrayList; | |
| import java.util.HashMap; | |
| import java.util.List; | |
| import java.util.Map; | |
| import java.util.NoSuchElementException; | |
| public class DomainDesignWithRepositories { | |
| // Um item do backlog é marcado como "concluído" quando a soma das horas restantes de todas as suas tarefas for igual a zero. | |
| public enum State { | |
| IN_PROGRESS, | |
| DONE | |
| } | |
| interface Repository<T, ID> { | |
| T findById(ID id); | |
| void save(T entity); | |
| } | |
| public static class TwoAggregates { | |
| public record Task(String id, int hoursRemaining) {} | |
| public record BacklogItem(String id, State state, List<String> taskIds) {} | |
| } | |
| public static void demonstrateTwoAggregates() { | |
| TwoAggregates.TaskRepository taskRepository = new TwoAggregates.TaskRepository(); | |
| TwoAggregates.BacklogItemRepository backlogItemRepository = new TwoAggregates.BacklogItemRepository(); | |
| TwoAggregates.Task task = new TwoAggregates.Task("CREATE_FIELD", 1); | |
| TwoAggregates.BacklogItem backlogItem = new TwoAggregates.BacklogItem("ADD_PRICE", State.IN_PROGRESS, List.of(task.id())); | |
| taskRepository.save(task); | |
| backlogItemRepository.save(backlogItem); | |
| TwoAggregates.Task taskToUpdate = taskRepository.findById("CREATE_FIELD"); | |
| TwoAggregates.Task updatedTask = new TwoAggregates.Task(taskToUpdate.id(), 0); | |
| taskRepository.save(updatedTask); | |
| TwoAggregates.BacklogItem fetchedBacklogItem = backlogItemRepository.findById("ADD_PRICE"); | |
| } | |
| public static class Anemic { | |
| public record Task(String id, int hoursRemaining) {} | |
| public record BacklogItem(String id, State state, List<Task> tasks) {} | |
| public static class BacklogItemService { | |
| private final BacklogItemRepository backlogItemRepository; | |
| private final TaskRepository taskRepository; | |
| public BacklogItemService(BacklogItemRepository repository, TaskRepository taskRepository) { | |
| this.backlogItemRepository = repository; | |
| this.taskRepository = taskRepository; | |
| } | |
| public void setHoursRemainingForTask(String backlogItemId, String taskId, int hours) { | |
| BacklogItem backlogItem = backlogItemRepository.findById(backlogItemId); | |
| List<Task> updatedTasks = new ArrayList<>(); | |
| backlogItem.tasks().forEach(task -> { | |
| if (task.id().equals(taskId)) { | |
| updatedTasks.add(new Task(task.id(), hours)); | |
| } else { | |
| updatedTasks.add(task); | |
| } | |
| }); | |
| int totalHoursRemaining = updatedTasks.stream().mapToInt(Task::hoursRemaining).sum(); | |
| State newState = (totalHoursRemaining == 0) ? State.DONE : backlogItem.state(); | |
| BacklogItem updatedBacklogItem = new BacklogItem(backlogItem.id(), newState, updatedTasks); | |
| backlogItemRepository.save(updatedBacklogItem); | |
| taskRepository.save(new Task(taskId, hours)); | |
| } | |
| } | |
| } | |
| public static void demonstrateAnemic() { | |
| Anemic.BacklogItemRepository repository = new Anemic.BacklogItemRepository(); | |
| Anemic.BacklogItem backlogItem = new Anemic.BacklogItem( | |
| "ADD_PRICE", State.IN_PROGRESS, List.of(new Anemic.Task("CREATE_FIELD", 1)) | |
| ); | |
| repository.save(backlogItem); | |
| Anemic.BacklogItemService service = new Anemic.BacklogItemService(repository); | |
| service.setHoursRemainingForTask("ADD_PRICE", "CREATE_FIELD", 0); | |
| } | |
| public static class OneAggregate { | |
| public record Task(String id, int hoursRemaining) {} | |
| public record BacklogItem(String id, State state, List<Task> tasks) { | |
| public BacklogItem setHoursRemainingForTask(String taskId, int hours) { | |
| List<Task> updatedTasks = this.tasks.stream() | |
| .map(task -> task.id().equals(taskId) ? new Task(task.id(), hours) : task) | |
| .toList(); | |
| int totalHoursRemaining = updatedTasks.stream().mapToInt(Task::hoursRemaining).sum(); | |
| State newState = (totalHoursRemaining == 0) ? State.DONE : this.state; | |
| return new BacklogItem(this.id, newState, updatedTasks); | |
| } | |
| } | |
| } | |
| public static void demonstrateOneAggregate() { | |
| OneAggregate.BacklogItemRepository repository = new OneAggregate.BacklogItemRepository(); | |
| OneAggregate.BacklogItem aggregateRoot = new OneAggregate.BacklogItem( | |
| "ADD_PRICE", State.IN_PROGRESS, List.of(new OneAggregate.Task("CREATE_FIELD", 1)) | |
| ); | |
| repository.save(aggregateRoot); | |
| OneAggregate.BacklogItem fetchedAggregate = repository.findById("ADD_PRICE"); | |
| OneAggregate.BacklogItem updatedAggregate = fetchedAggregate.setHoursRemainingForTask("CREATE_FIELD", 0); | |
| repository.save(updatedAggregate); | |
| } | |
| public static void main(String[] args) { | |
| demonstrateAnemic(); | |
| demonstrateTwoAggregates(); | |
| demonstrateOneAggregate(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment