Skip to content

Add Spring Boot Examples to Lab 3 (Generation and Refactoring) #26

@shawnewallace

Description

@shawnewallace

Lab 3 Java/Spring Boot Version Complete

Created a separate Java version of Lab 3 following the successful Lab 2 pattern for focused, stack-specific learning.

Changes Summary

New File: docs/labs/lab-03-generation-and-refactoring-java.md

  • Size: 1,053 lines (complete Spring Boot adaptation)
  • Commit: 85fefc1

Updated Files:

  • lab-03-generation-and-refactoring.md - Added cross-reference to Java version
  • docs/labs/README.md - Updated Lab 3 section with both versions

Java/Spring Boot Content

Part 1: Generate REST API Endpoints (CRUD Operations)

Service Layer Methods:

  • findAllTasks(TaskStatus status) with optional filtering
  • findTaskById(UUID id) returning Optional
  • updateTask(UUID id, UpdateTaskRequest request) with @transactional
  • deleteTask(UUID id) with EntityNotFoundException

Controller Endpoints:

  • GET /api/tasks with optional status query parameter
  • GET /api/tasks/{id} returning 200 OK or 404 Not Found
  • PUT /api/tasks/{id} with UpdateTaskRequest DTO
  • DELETE /api/tasks/{id} returning 204 No Content

Spring Boot Patterns:

Testing:

  • JUnit 5 unit tests for service layer with Mockito
  • Integration testing patterns with @SpringBootTest

Part 2: Refactor Legacy Code

Before Issues:

  • No Spring annotations
  • Nested if statements (6+ levels)
  • Thread.sleep() blocking operations
  • Swallowed exceptions (empty catch blocks)
  • No logging
  • Magic numbers and poor naming
  • String concatenation in loops
  • Mixed concerns

After Improvements:

  • @service with @slf4j annotations
  • @requiredargsconstructor for constructor injection
  • Guard clauses (early returns)
  • Proper exception handling with logging
  • ProcessingResult value object
  • ProcessingType enum
  • StringBuilder for efficiency
  • Extracted methods: processSingleTask(), isTaskValid(), executeTaskProcessing()
  • SLF4J structured logging with parameters

Expected Refactored Structure:

@Service
@Slf4j
@RequiredArgsConstructor
public class RefactoredTaskProcessor {
    private final TaskRepository taskRepository;
    private final TaskOutputWriter taskOutputWriter;
    
    public ProcessingResult processTaskBatch(List<TaskItem> tasks) {
        // Guard clauses
        // Process with proper error handling
        // Return comprehensive result
    }
}

Part 3: Object Calisthenics

Wrap Primitives:

  • TaskId value object with @embeddable annotation
  • Priority enum with validation
  • TaskStatus enum
  • JPA @EmbeddedId for value objects

First-Class Collections:

  • TaskCollection wrapping List
  • Immutable views with List.copyOf()
  • Domain-specific operations (findById, filterByStatus)

No Abbreviations:

  • Expanded: var tTask task
  • Expanded: var resOptional<Task> result
  • Expanded: int cntint itemCount

Tell, Don't Ask:

  • Replace getters with behavior methods
  • task.isCompleted() instead of checking status + completedAt

Part 4: Multi-File Refactoring

  • Copilot Edits for consistent changes
  • Working set management
  • Review process for AI-generated changes
  • Same concepts as .NET version

Extension Exercises

  1. Pagination: Spring Data Pageable with PageRequest
  2. Sorting: Sort.by() with multiple fields
  3. Response Mapper: Dedicated TaskResponseMapper component

Design Decision: Separate Files

Continuing the Lab 2 pattern:

Better Focus: Java developers see only Spring Boot patterns
Manageable Size: 758 (.NET) vs 1,053 (Java) lines
Clear Examples: Spring-specific annotations and patterns
Easy Comparison: Cross-links for developers learning both stacks

Epic #16 Progress

With this completion: 6 of 15 issues complete (40%)

Next Steps

Continue with:

Lab 3 ready for Workshop 2.0 with both .NET and Java/Spring Boot support! 🎉

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions