Skip to content

Instantly share code, notes, and snippets.

@kaelfeitosa
Created October 14, 2025 17:37
Show Gist options
  • Select an option

  • Save kaelfeitosa/4efd7a563ef473ea1811a6e808a807d4 to your computer and use it in GitHub Desktop.

Select an option

Save kaelfeitosa/4efd7a563ef473ea1811a6e808a807d4 to your computer and use it in GitHub Desktop.
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