Introduction
FoodTech Kitchen Service implements a Hexagonal Architecture (Ports & Adapters) following Clean Architecture principles. The system automates the decomposition of restaurant orders into station-specific tasks.This architecture ensures complete separation of business logic from infrastructure concerns, making the system highly testable and maintainable.
The Problem We Solve
When a restaurant order contains multiple products (drinks, hot dishes, salads), the system automatically:- Groups products by their kitchen station
- Creates specific preparation tasks for each station
- Executes preparation commands with station-appropriate workflows
BAR Station
Handles all beverages and cocktails
- 3 seconds per drink
- Parallel preparation possible
Hot Kitchen
Prepares hot dishes and soups
- 7 seconds per dish
- Sequential cooking required
Cold Kitchen
Assembles salads and desserts
- 5 seconds per dish
- Fresh ingredient handling
Architectural Layers
The system is organized into three concentric layers, each with distinct responsibilities:Domain Layer (Core)
The innermost layer contains pure business logic with zero external dependencies.Domain Components
Domain Components
Entities:
Order: Represents a customer order with table number and productsTask: Represents a station-specific preparation task with lifecycleProduct: Individual items with type (DRINK, HOT_DISH, COLD_DISH)
PrepareDrinkCommand: Executes beverage preparationPrepareHotDishCommand: Executes hot dish cookingPrepareColdDishCommand: Executes cold dish assembly
TaskDecomposer: Breaks orders into station-specific tasksTaskFactory: Creates task instancesCommandFactory: Creates appropriate commands per stationOrderValidator: Enforces business rules
Application Layer (Orchestration)
Orchestrates business logic through use cases without knowing infrastructure details.Infrastructure Layer (Technical Details)
Provides concrete implementations of ports using specific technologies.REST Adapter
Exposes HTTP endpoints for external clients
- Maps DTOs to domain objects
- Handles HTTP concerns (status codes, validation)
Persistence Adapter
Implements repository interfaces using JPA
- Maps domain objects to JPA entities
- Manages database transactions
Dependency Rule
Key Benefits
Testability
Maintainability
- Change database? Only modify persistence adapters
- Switch from REST to GraphQL? Only modify API adapters
- Add new station type? Extend domain with new command, no infrastructure changes
Technology Independence
The core business logic (Domain + Application layers) has zero knowledge of:- Spring Framework
- JPA/Hibernate
- HTTP/REST
- Jackson (JSON)
- H2 Database
- Portable across frameworks
- Testable without containers
- Evolvable without breaking changes
Request Flow Example
Let’s trace a complete order through all layers:Notice how each layer performs its specific responsibility without knowledge of adjacent layers’ implementation details.
Project Structure
The physical file structure mirrors the logical architecture:Design Principles Applied
Single Responsibility
Each class has one reason to change
OrderController: Handle HTTPProcessOrderUseCase: Orchestrate flowOrderRepositoryAdapter: Persist data
Open/Closed
Open for extension, closed for modification
- Add new station: Create new command
- No changes to existing code
Dependency Inversion
Depend on abstractions, not concretions
- Use cases depend on
OrderRepositoryinterface - Adapters implement the interface
Interface Segregation
Small, focused interfaces
ProcessOrderPorthas one method- Clients don’t depend on unused methods
Next Steps
Hexagonal Details
Deep dive into ports and adapters pattern
Command Pattern
Learn how commands encapsulate station logic
Layer Interactions
Understand how layers communicate