Design Patterns
Design patterns are named solutions to recurring design problems — not copy-paste code, but shared vocabulary that lets engineers communicate architecture in one word instead of…
Introduction
Design patterns are named solutions to recurring design problems — not copy-paste code, but shared vocabulary that lets engineers communicate architecture in one word instead of twenty. When a staff engineer says "use Strategy for payment rails" or "Observer for side effects," the team immediately understands structure, trade-offs, and Spring wiring.
Enterprise Java — especially Spring Boot — is pattern-heavy by design. The Spring container itself is a Singleton registry and Factory. @Autowired injection implements Strategy. @EventListener is Observer. Legacy gateway adapters wrap third-party APIs with the Adapter pattern. Lombok-free domain objects use Builder for complex construction.
This lesson covers six patterns every Java engineer must recognize in production codebases: Singleton, Factory, Builder, Strategy, Observer, and Adapter — with banking examples and Spring Framework mappings you will encounter from day one on a fintech team.
Business problem
Teams without pattern vocabulary rebuild the same broken designs:
- Switch statements everywhere: Payment type routing via if/else — adding BNPL means editing 12 files instead of one new Strategy bean.
- Tight coupling: TransferService directly instantiates legacy SOAP client — vendor migration requires rewriting business logic.
- Constructor hell:
new Payment(id, amount, currency, fee, tax, metadata, ...)with 15 parameters — wrong argument order causes silent production bugs. - Side-effect spaghetti: Transfer method calls audit, email, fraud, analytics inline — one failure rolls back entire transaction.
- Multiple singletons: Hand-rolled
DatabaseConnection.getInstance()fights Spring's singleton scope — double instances, connection leaks.
Why this topic exists
Patterns exist to capture proven solutions and prevent repeated mistakes:
- Shared vocabulary: "Strategy" in a design doc beats three paragraphs of interface + impl explanation.
- Change isolation: Patterns encode SOLID — Strategy enables OCP, Observer enables SRP for side effects.
- Framework alignment: Spring Boot idioms map directly to Gang of Four patterns — learn both together.
- Interview and review standard: Staff loops expect pattern recognition — refactor suggestions reference patterns by name.
- Legacy integration: Adapter pattern is how enterprises wrap 20-year-old mainframe APIs without contaminating modern services.
Core concepts
Six essential patterns — problem, solution, Spring mapping:
- Singleton: Exactly one instance. Problem: shared config/connection pool. Solution: private constructor + static accessor. Spring: default bean scope is singleton — prefer container over hand-rolled.
- Factory: Create objects without exposing construction logic. Problem: complex instantiation rules. Solution:
PaymentProcessorFactory.create(type). Spring:@Beanmethods in @Configuration are factories. - Builder: Construct complex objects step-by-step. Problem: telescoping constructors. Solution: fluent API
Payment.builder().amount().currency().build(). Spring: test data builders; domain object construction. - Strategy: Encapsulate interchangeable algorithms. Problem: payment rail varies by type. Solution:
PaymentProcessorinterface + ACH/Wire impls. Spring: inject interface; @Profile selects strategy. - Observer: Notify dependents on state change. Problem: transfer triggers audit, email, fraud. Solution: publish event, listeners react. Spring:
ApplicationEventPublisher+@EventListener. - Adapter: Convert incompatible interface to expected one. Problem: legacy SOAP API vs modern REST service. Solution:
LegacyPaymentAdapter implements PaymentProcessor. Spring: @Service adapter wrapping external client.
Internal architecture
Pattern composition in a payment microservice:
┌──────────────── PaymentController ──────────────────────────────────────────┐