1. Architecture Overview
Java Design Patterns is a Maven multi-module educational repository containing 166 self-contained design pattern implementations in Java. The project is structured as a flat collection of independent modules under a single parent POM — there is no runtime application, no deployment target, and no central entry point. Each module is a standalone unit that can be built, tested, and run independently.
The architecture is intentionally simple: a parent POM defines shared dependencies and plugin configuration, and each pattern module inherits from it while adding only pattern-specific code. The project's value is in its breadth, consistency, and educational quality — not in runtime complexity.
java-design-patterns/ (parent POM, aggregator)
├── abstract-document/ (pattern module)
│ ├── pom.xml (inherits parent)
│ ├── README.md (pattern documentation)
│ ├── etc/ (UML diagrams)
│ └── src/
│ ├── main/java/com/iluwatar/... (implementation + App.java)
│ └── test/java/com/iluwatar/... (JUnit 5 tests)
├── abstract-factory/ (same structure)
├── ... (164 more pattern modules)
├── localization/ (18+ language translations)
│ ├── ar/ (Arabic)
│ ├── zh/ (Chinese)
│ └── ...
└── pom.xml (root parent POM)
Component Inventory
| Component | Path | Role |
|---|---|---|
| Root POM | pom.xml |
Dependency management, plugin config, module aggregation |
| Pattern modules (×166) | <pattern>/ |
Self-contained pattern implementations |
| Localization | localization/<lang>/ |
Translated README files |
| UML diagrams | <pattern>/etc/ |
Class diagrams (.urm.png, .png) |
| Entry points | <pattern>/src/main/java/.../App.java |
Runnable demo for each pattern |
| Tests | <pattern>/src/test/java/ |
JUnit 5 unit tests |
Technology Stack
| Technology | Version | Purpose |
|---|---|---|
| Java | 17+ | Language runtime |
| Maven | 3.9+ | Build system, dependency management |
| JUnit 5 | 5.11.4 | Testing framework |
| Mockito | 5.14.2 | Mocking framework |
| Lombok | 1.18.38 | Boilerplate reduction (@Slf4j, @Getter, etc.) |
| SLF4J | 2.0.17 | Logging facade |
| Logback | 1.5.18 | Logging implementation |
| Spring Boot | 3.4.4 | Web framework (microservices and web-pattern modules only) |
| H2 | 2.3.232 | In-memory database (data access pattern modules) |
| MongoDB Driver | 5.4.0 | MongoDB client (select modules) |
| Gson | 2.11.0 | JSON serialization (select modules) |
| Guice | 6.0.0 | Dependency injection (DI pattern module) |
| HtmlUnit | 4.17.0 | Web testing (web-pattern modules) |
| JaCoCo | 0.8.13 | Code coverage |
| SonarCloud | 5.1.0.4751 | Static analysis |
Note
Not every module uses every dependency. Spring Boot, H2, MongoDB, Guice, and HtmlUnit are only present in the modules that specifically demonstrate those technologies. Most pattern modules depend only on SLF4J/Logback, Lombok, and JUnit 5.
2. System Requirements
Development Environment
| Requirement | Specification |
|---|---|
| JDK | 17+ (OpenJDK, Oracle JDK, or any conformant distribution) |
| Maven | 3.9+ |
| Git | 2.x |
| Disk | ~200 MB source, ~500 MB compiled, ~1.5 GB with full .m2/repository |
| RAM | 4 GB recommended for full build; 2 GB for single-module builds |
| OS | Any (Linux, macOS, Windows) — pure Java, no native dependencies |
CI Environment
| Requirement | Specification |
|---|---|
| SonarCloud | Organization iluwatar, project key iluwatar_java-design-patterns |
| JaCoCo | Integrated via Maven plugin for coverage reporting |
Important
The project has no runtime deployment requirements. It is a build-and-run-locally educational resource. There are no containers, no cloud deployments, and no production servers to manage.
3. Configuration Reference
The project has minimal configuration. All settings live in the root pom.xml as Maven properties.
Maven Properties (root pom.xml)
| Property | Value | Purpose |
|---|---|---|
project.build.sourceEncoding |
UTF-8 |
Source file encoding |
spring-boot.version |
3.4.4 |
Spring Boot version for web-pattern modules |
junit.version |
5.11.4 |
JUnit Jupiter version |
mockito.version |
5.14.2 |
Mockito version |
logback.version |
1.5.18 |
Logback logging version |
slf4j.version |
2.0.17 |
SLF4J facade version |
jacoco.version |
0.8.13 |
Code coverage plugin version |
commons-dbcp.version |
1.4 |
Database connection pool |
htmlunit.version |
4.17.0 |
Headless browser for web tests |
gson.version |
2.11.0 |
Google JSON library |
guice.version |
6.0.0 |
Google Guice DI |
system-lambda.version |
1.1.0 |
JUnit system exit/out capturing |
lombok.version |
1.18.38 |
Project Lombok |
mongo.version |
5.4.0 |
MongoDB driver |
bson.version |
5.4.0 |
BSON library |
h2.version |
2.3.232 |
H2 embedded database |
maven-surefire-plugin.version |
3.5.2 |
Test runner |
license-maven-plugin.version |
5.0.0 |
License header enforcement |
maven-compiler-plugin.version |
3.14.0 |
Java compiler plugin |
SonarCloud Properties
| Property | Value |
|---|---|
sonar.host.url |
https://sonarcloud.io |
sonar.organization |
iluwatar |
sonar.projectKey |
iluwatar_java-design-patterns |
sonar.moduleKey |
${project.artifactId} |
sonar.projectName |
Java Design Patterns |
Additional Repositories
| Repository | URL | Purpose |
|---|---|---|
| JitPack | https://jitpack.io |
GitHub-based dependency resolution |
Tip
To override any version locally without modifying
pom.xml, pass it as a Maven property:mvn install -Djunit.version=5.12.0 -DskipTests
4. Deployment & Scaling
This project is not deployed as a service. It is a source-code repository used for learning. The relevant operational concerns are:
Website
The project website at https://java-design-patterns.com/ is maintained separately. Pattern pages on the website are generated from the module README files using a static site generator.
Repository Hosting
| Aspect | Detail |
|---|---|
| Host | GitHub |
| URL | https://github.com/iluwatar/java-design-patterns |
| Branch model | master (primary branch) |
| CI | GitHub Actions with SonarCloud integration |
Scaling the Module Count
Adding new pattern modules involves:
- Create the module directory with the standard structure
- Add the
<module>entry to the rootpom.xml<modules>section (alphabetical order) - Create a
pom.xmlinheriting from the parent:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iluwatar</groupId>
<artifactId>java-design-patterns</artifactId>
<version>1.26.0-SNAPSHOT</version>
</parent>
<artifactId>my-new-pattern</artifactId>
<dependencies>
<!-- pattern-specific deps only -->
</dependencies>
</project>
Note
The project currently contains 166 modules. Maven handles this scale well, but full builds take several minutes. Use
-pl <module> -amfor targeted builds during development.
5. Operations
Build Operations
Full build (skip tests):
mvn clean install -DskipTests
Full build with tests:
mvn clean install
Single module build:
mvn compile -pl observer -am
Run a pattern demo:
cd <module>
mvn exec:java -Dexec.mainClass="com.iluwatar.<package>.App"
Run tests for one module:
mvn test -pl <module>
Tip
Use
mvn -T 1C install -DskipTeststo enable parallel builds (1 thread per CPU core). This can cut full build time significantly on multi-core machines.
Code Quality Operations
Run SonarCloud analysis:
mvn sonar:sonar \
-Dsonar.host.url=https://sonarcloud.io \
-Dsonar.organization=iluwatar \
-Dsonar.projectKey=iluwatar_java-design-patterns
Generate code coverage report:
mvn test jacoco:report
Coverage reports are generated per module at <module>/target/site/jacoco/index.html.
Verify license headers:
mvn license:check
Note
The license plugin enforces the MIT license header on all source files. The
model-view-viewmodelmodule is an exception — it uses the ZK framework under LGPL.
Dependency Management
Check for dependency updates:
mvn versions:display-dependency-updates
Check for plugin updates:
mvn versions:display-plugin-updates
Resolve all dependencies (useful for CI caching):
mvn dependency:go-offline
Common Maintenance Tasks
| Task | Command |
|---|---|
| Clean all build artifacts | mvn clean |
| Rebuild from scratch | mvn clean install -DskipTests |
| Update all version properties | Edit root pom.xml <properties> block |
| Add a new pattern module | See section 4 (Deployment & Scaling) |
| Generate site documentation | mvn site (per module) |
6. Performance
Build Performance
Full build characteristics on modern hardware:
| Metric | Approximate Value |
|---|---|
| Full compile (skip tests) | 3–5 minutes |
| Full compile + test | 8–15 minutes |
| Single module compile | 5–15 seconds |
| Single module test | 10–30 seconds |
Tip
For the fastest iteration during development, combine
-pl,-am, and Maven's-o(offline) flag after the first full build:mvn test -pl observer -am -o
Memory Usage
| Operation | Recommended Heap |
|---|---|
| Single module build | Default (256 MB) |
| Full project build | MAVEN_OPTS="-Xmx2g" |
| IDE import (all modules) | 4 GB IDE heap |
7. Security
License Compliance
| Module | License |
|---|---|
| All modules (except MVVM) | MIT |
model-view-viewmodel |
LGPL (ZK framework dependency) |
The MIT license is permissive — pattern code can be freely copied, modified, and used in commercial projects. The LGPL-licensed MVVM module requires compliance with LGPL terms if distributed as a library.
Warning
If you extract code from the
model-view-viewmodelmodule for use in a proprietary project, review LGPL requirements carefully. The ZK framework dependency triggers LGPL obligations.
Dependency Security
The project uses well-known, actively maintained dependencies. Key security considerations:
| Dependency | Security Note |
|---|---|
| Spring Boot 3.4.4 | Keep updated — Spring publishes regular security patches |
| H2 2.3.232 | Used only in tests/demos with in-memory databases — no production exposure |
| MongoDB Driver 5.4.0 | Used only in demo modules — no real database connections |
| Gson 2.11.0 | JSON parsing — minimal attack surface in demo context |
| Lombok 1.18.38 | Compile-time only — no runtime footprint |
Caution
Some pattern demos (e.g.,
serialized-entity,serialized-lob) use Java serialization. Do not use Java serialization with untrusted data in production systems — it is a known attack vector. These modules demonstrate the pattern concept only.
No Secrets or Credentials
The repository contains no secrets, API keys, database credentials, or sensitive configuration. All data access patterns use in-memory H2 databases or mock data.
8. Developer Internals
Repository Structure
java-design-patterns/
├── pom.xml Root POM (aggregator + dependency management)
├── lgpl-3.0.txt LGPL license for ZK framework
├── LICENSE.md MIT license
│
├── abstract-document/ Pattern module (×166, all same structure)
│ ├── README.md Pattern docs (intent, examples, diagrams)
│ ├── pom.xml Module POM (inherits root)
│ ├── etc/ UML class diagrams
│ │ └── abstract-document.urm.png
│ └── src/
│ ├── main/java/com/iluwatar/abstractdocument/
│ │ ├── App.java Entry point demo
│ │ ├── AbstractDocument.java
│ │ ├── Document.java Core interface
│ │ └── domain/ Domain objects (Car, Part, etc.)
│ └── test/java/com/iluwatar/abstractdocument/
│ ├── AbstractDocumentTest.java
│ └── AppTest.java
│
├── localization/ Translated READMEs
│ ├── ar/ Arabic (most complete)
│ ├── bn/ Bengali
│ ├── da/ Danish
│ ├── de/ German
│ ├── el/ Greek
│ ├── es/ Spanish
│ ├── fa/ Persian
│ ├── fr/ French
│ ├── hi/ Hindi
│ ├── id/ Indonesian
│ ├── it/ Italian
│ ├── ja/ Japanese
│ ├── mr/ Marathi
│ ├── ne/ Nepali
│ ├── pt/ Portuguese
│ ├── ru/ Russian
│ ├── si/ Sinhala
│ ├── tr/ Turkish
│ ├── ur/ Urdu
│ └── zh/ Chinese
│
└── (no other top-level directories)
Architecture Deep Dive
Parent POM Pattern
The root pom.xml uses Maven's <packaging>pom</packaging> aggregator pattern. It defines:
<modules>— All 166 pattern modules listed alphabetically<dependencyManagement>— Version-locked dependencies available to all modules<properties>— Centralized version strings<build><pluginManagement>— Shared plugin configuration (compiler, surefire, JaCoCo, license)<repositories>— JitPack for GitHub-hosted dependencies
Child modules inherit the parent and only declare the dependencies they actually need, without specifying versions (they inherit from <dependencyManagement>).
Module Independence
Each pattern module is fully self-contained:
- No cross-module dependencies. Pattern A never imports from pattern B
- No shared library module. Common utilities (if any) are duplicated by design
- No shared resources. Each module manages its own test data and config
This strict isolation means:
- Any module can be extracted and used independently
- Build failures in one module do not cascade
- New patterns can be added without touching existing code
Note
The only shared elements are the parent POM's dependency versions and the Lombok/SLF4J transitive dependencies that all modules use.
Entry Point Convention
Every pattern provides App.java at src/main/java/com/iluwatar/<patternpackage>/App.java with a public static void main(String[] args) method. This method:
- Sets up the pattern participants (creates objects, wires dependencies)
- Executes the pattern's core behavior
- Logs output via SLF4J to demonstrate the result
The entry point serves as a living code example — it is both documentation and executable demo.
Test Convention
Every pattern provides test classes alongside the implementation:
AppTest.java— VerifiesApp.main()runs without exceptions<PatternClass>Test.java— Unit tests for individual pattern participants- Tests use JUnit 5 (
@Test,assertThat,assertThrows) - Mockito for behavior verification where needed
system-lambdafor capturingSystem.outoutput in tests
Module Reference
The following modules have source code analyzed in detail (HIGH-priority modules with source content):
Pipeline Pattern (pipeline/)
Demonstrates ordered processing stages. Key classes:
| Class | Role |
|---|---|
Pipeline<I,O> |
Fluent builder that chains Handler stages |
Handler<I,O> |
Functional interface for a single processing stage |
RemoveAlphabetsHandler |
Stage: strips alphabetic characters |
RemoveDigitsHandler |
Stage: strips numeric characters |
ConvertToCharArrayHandler |
Stage: converts String to char[] |
Usage:
var filters = new Pipeline<>(new RemoveAlphabetsHandler())
.addHandler(new RemoveDigitsHandler())
.addHandler(new ConvertToCharArrayHandler());
var output = filters.execute("GoYankees123!");
Reactor Pattern (reactor/)
NIO-based event demultiplexing with Spring-like channel handlers. Key classes:
| Class | Role |
|---|---|
NioReactor |
Event loop using java.nio.channels.Selector |
AbstractNioChannel |
Base for TCP/UDP channels |
NioDatagramChannel |
UDP channel implementation |
NioServerSocketChannel |
TCP server socket channel |
ChannelHandler |
Interface for event processing callbacks |
App |
Wires up TCP (port 16666) and UDP (port 16668) channels |
Observer Pattern (observer/)
Classic publish-subscribe with weather data. Key classes:
| Class | Role |
|---|---|
Weather |
Subject that notifies registered observers on state change |
WeatherObserver |
Observer interface with update(WeatherType) |
Orcs / Hobbits |
Concrete observers that react to weather changes |
WeatherType |
Enum: SUNNY, RAINY, WINDY, COLD |
Flux Pattern (flux/)
Unidirectional data flow. Key classes:
| Class | Role |
|---|---|
Dispatcher |
Singleton that routes Action objects to registered Store instances |
Store |
Abstract base for state containers (ContentStore, MenuStore) |
Action |
Typed event object (Content, MenuItem payloads) |
View |
Abstract base for UI components that observe stores |
Event Sourcing (event-sourcing/)
Persists state as an immutable event log. Demonstrates DomainEventProcessor dispatching AccountCreateEvent, MoneyDepositEvent, MoneyTransferEvent to reconstruct state.
Service Layer (service-layer/)
Application boundary pattern with MagicService → SpellDao, SpellbookDao, WizardDao. Uses @Transactional-style patterns with in-memory data.
CQRS (command-query-responsibility-segregation/)
Separate read (QueryService) and write (CommandService) models operating on Author and Book entities.
Layered Architecture (layered-architecture/)
Clean separation into presentation → service → persistence layers using CakeBakingService, CakeDao, CakeToppingDao.
Code Patterns and Conventions
Naming Conventions
| Element | Convention | Example |
|---|---|---|
| Module directory | kebab-case |
chain-of-responsibility |
| Package | com.iluwatar.<flattened> |
com.iluwatar.chainofresponsibility |
| Entry point | App.java |
Always App |
| Test classes | <Class>Test.java |
SingletonTest.java |
| Interfaces | Descriptive nouns | Document, Handler, Observer |
| Enums | PascalCase |
WeatherType, KingdomType |
Logging
All modules use SLF4J with Logback. Most use Lombok's @Slf4j annotation:
@Slf4j
public class App {
public static void main(String[] args) {
LOGGER.info("Starting pattern demo");
}
}
Some older modules use explicit logger creation:
private static final Logger logger = LoggerFactory.getLogger(App.class.getName());
Lombok Usage
| Annotation | Usage |
|---|---|
@Slf4j |
Logger injection (most modules) |
@Getter / @Setter |
Property access (domain objects) |
@Data |
Full data class generation |
@Builder |
Builder pattern on domain objects |
@RequiredArgsConstructor |
Constructor injection |
Modern Java Features
The codebase uses modern Java idioms throughout:
varfor local variable type inference- Switch expressions with arrow syntax
- Streams and lambdas for functional-style processing
Map.of(),List.of()for immutable collection literalsOptionalfor nullable return valuesrecordtypes where appropriate
Testing Strategy
Test Framework
- JUnit 5 (Jupiter) for all test classes
- Mockito 5 for mock creation and verification
- system-lambda for capturing
System.outandSystem.exitin tests - HtmlUnit for web-pattern integration tests
Test Coverage
The project uses JaCoCo for code coverage. Coverage reports are generated per-module and aggregated by SonarCloud.
# Generate coverage for a single module
mvn test jacoco:report -pl observer
# View the report
open observer/target/site/jacoco/index.html
Test Categories
| Category | Example | Purpose |
|---|---|---|
AppTest |
Runs App.main() |
Smoke test — pattern demo doesn't crash |
| Unit tests | SingletonTest |
Verify pattern behavior with assertions |
| Integration tests | AntiCorruptionLayerTest |
Spring Boot context tests |
| Web tests | CompositeViewTest |
HtmlUnit browser simulation |
Note
Concurrency pattern tests are inherently timing-sensitive. The project has a known open issue (#2977) regarding busy-waiting loops that can cause intermittent test failures under load.
Potential Improvements
Based on source analysis and community issues:
| Area | Improvement | Context |
|---|---|---|
| Busy-waiting | Replace Thread.sleep() loops with CountDownLatch/CompletableFuture |
#2977 — long-standing issue with 47 comments |
| New patterns | Thread-Specific Storage | #3225 — community requested |
| Logger consistency | Migrate remaining manual LoggerFactory.getLogger() to Lombok @Slf4j |
Some older modules use manual logger creation |
| Java version | Leverage Java 21 LTS features (virtual threads, pattern matching) | Would modernize concurrency patterns |
| Dependency versions | Regular dependency update sweep | Spring Boot, JUnit, and other deps evolve frequently |
Contributing Guide
Prerequisites
- JDK 17+
- Maven 3.9+
- Understanding of the design pattern being contributed
Adding a New Pattern
- Research — Ensure the pattern is documented in authoritative literature and is not already implemented
- Create module directory with standard structure (see section 4)
- Write the implementation following existing conventions:
App.javaas entry point with SLF4J logging- Clean separation of pattern participants into individual files
- Use Lombok where appropriate
- Write comprehensive tests:
AppTest.java— verifymain()runs without exception- Unit tests for each pattern participant
- Edge case tests
- Write the README following the template:
- Intent (with YAML frontmatter:
title,shortTitle,category,language,tag) - Real-world analogy
- In plain words
- Programmatic example with code blocks
- Class diagram (generate UML and place in
etc/) - Applicability
- Known uses (JDK/real-world examples)
- Consequences
- Related patterns
- Credits
- Intent (with YAML frontmatter:
- Add module to root
pom.xml<modules>in alphabetical order - Run full test suite to verify no regressions:
mvn test - Submit pull request with pattern name and category in the title
README Frontmatter Format
---
title: Pattern Name
shortTitle: Pattern Name
category: Creational|Structural|Behavioral|Concurrency|...
language: en
tag:
- Gang of Four
- Extensibility
- Performance
---
Code Style
- Follow existing patterns for consistency
- Use
@Slf4jfor logging (not manualLoggerFactory.getLogger()) - Use
varfor local variables where type is obvious - Keep classes small and focused — one file per pattern participant
- No external code formatters are enforced, but match surrounding code style
- License header (MIT) required on all Java files — enforced by
license-maven-plugin
Important
Every Java source file must include the MIT license header. Run
mvn license:checkto verify compliance before submitting a pull request. The header mentions the LGPL exception for themodel-view-viewmodelmodule.
9. Integration Points
SonarCloud
The project integrates with SonarCloud for continuous code quality analysis:
- Organization:
iluwatar - Project key:
iluwatar_java-design-patterns - Quality gates: Applied per-module via
sonar.moduleKey=${project.artifactId} - Coverage: JaCoCo reports are uploaded automatically during analysis
JitPack
JitPack is configured as an additional Maven repository for dependencies hosted on GitHub that are not available on Maven Central:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
Website
Pattern READMEs serve as the source content for the project website at https://java-design-patterns.com/. The YAML frontmatter in each README (title, shortTitle, category, language, tag) provides metadata for website navigation, categorization, and search.
Tip
When writing or updating a pattern README, ensure the YAML frontmatter is present and correctly formatted — it directly affects how the pattern appears on the website.