* feat: add Microservices Bulkhead pattern (#3228)
* fix: cancel queued calls on bulkhead shutdown
Shutdown now cancels the queued futures so callers do not hang, a shutdown racing a submit is no longer counted as a rejection, and interrupted inventory checks are logged. The class diagram is a rendered PNG.
---------
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
* feat: add Microservices Load Shedding pattern (#3229)
* fix: harden load shedder release and report the admitted count
release() clamps the in-flight count at zero, acquire() returns the admitted count that the service logs, and the demo summary reports the total shed. The class diagram is a rendered PNG.
* Add transactional-outbox module
Introduce a new transactional-outbox Maven module demonstrating the Transactional Outbox pattern. Adds a Spring Boot sample app and README explaining the pattern. New code includes Order and OutboxEvent entities, OrderStatus/EventStatus enums, Spring Data repositories (OrderRepository, OutboxRepository), OrderService (atomic write of order + outbox), OutboxPublisher (scheduled poll & publish), MessageBroker interface and MessageConsumer implementation, and App entrypoint. Includes unit tests (AppTest, OrderServiceTest, OutboxPublisherTest). Root pom.xml updated to register the new module. Module uses Spring Data JPA, Spring Web, Lombok, H2 and standard test dependencies.
* Add OutboxPublisher edge-case tests
Add two unit tests for OutboxPublisher: one verifies processOutboxEvents returns an empty list when there are no pending events; the other simulates a MessageBroker exception to ensure the event status is set to FAILED and the repository.save is called. Added necessary Mockito and assertion imports to support the tests.
* Use MockitoExtension for OutboxPublisher test
Replace the legacy inline/mock-based test with a JUnit5 + MockitoExtension unit test. Adds OutboxPublisherUnitTest (uses @ExtendWith(MockitoExtension.class), @Mock and @InjectMocks) that verifies broker exceptions mark events as FAILED and that the repository.save(...) is called. Removes the duplicate inline-mocking test and unused Mockito imports from OutboxPublisherTest.
* Replace Lombok @Slf4j with explicit Logger
Remove Lombok's @Slf4j and add explicit org.slf4j.Logger/LoggerFactory fields in transactional-outbox classes.
This makes logging explicit and removes reliance on Lombok's @Slf4j annotation.
* Add scheduled wrapper for outbox publishing
Introduce publishOutboxEvents() annotated with @Scheduled(fixedDelay = 5000) that delegates to the existing processOutboxEvents(). This separates the scheduling concern from the transactional processing method; processOutboxEvents() remains @Transactional and now only handles fetching and dispatching pending OutboxEvent items.
* Use UTC timestamps and add OutboxPublisher ctor
Use UTC for timestamps in OrderService and OutboxPublisher by switching LocalDateTime.now() to LocalDateTime.now(ZoneOffset.UTC). Replace Lombok @RequiredArgsConstructor on OutboxPublisher with an explicit constructor for dependency injection and remove the @Transactional annotation from processOutboxEvents. Update processedAt assignment to use UTC as well.
Add Brazilian Portuguese (pt) translations for three previously
untranslated pattern READMEs, following the existing localization/pt/
convention documented in the wiki (15. Support for multiple languages).
Frontmatter and section headers follow the same structure used by the
most recently updated existing translation (singleton), keeping code
blocks, links, and image references unchanged from the English source.
* Initialize microservices-messaging Spring Boot project
Add initial project structure for microservices-messaging using Spring Boot. Includes Maven configuration with dependencies for Kafka, Lombok, and testing, as well as main application, test class, and application properties.
* Initialize microservices messaging pattern
1. Added initial project structure for demonstrating the microservices messaging pattern.
2. Introduced service stubs (OrderService, InventoryService, PaymentService, NotificationService), a Message and MessageBroker class, and a main App entry point.
3. Added README and logging configuration.
* Implement Message and MessageBroker classes
1. Added the Message class with unique ID, content, and timestamp fields, and a toString method.
2. Implemented the MessageBroker class to support topic-based publish-subscribe messaging, including subscriber management, message publishing, and logging.
* Implement messaging pattern for microservices
1. Added message handling logic to InventoryService, PaymentService, and NotificationService.
2. OrderService now publishes order events to a MessageBroker, and App demonstrates the messaging workflow. 3. Each service processes relevant order events and logs actions for demonstration purposes.
* Expand microservices messaging docs and add diagrams
1. Enhanced the README with detailed explanations, real-world examples, Java code samples, and references for the Microservices Messaging pattern.
2. Added flowchart and sequence diagram images to illustrate the pattern.
* Refactor to use Kafka for microservices messaging
1. Added Apache Kafka for asynchronous communication between services.
2. Added KafkaMessageProducer and KafkaMessageConsumer classes, updated service implementations and main application logic to use Kafka, and adjusted the Maven configuration to include Kafka and Jackson dependencies.
3. Updated and moved all classes to the com.iluwatar.messaging package, improved documentation, and updated diagrams to reflect the new architecture.
* Add unit tests and license headers to messaging module
1. Added comprehensive unit tests for App, InventoryService, KafkaMessageConsumer, KafkaMessageProducer, Message, NotificationService, OrderService, and PaymentService.
2. Added MIT license headers to all main source files and logback.xml.
3. Updated pom.xml to include JUnit Jupiter as a test dependency.
* Refactor and simplify service and Kafka test classes
1. Simplified unit tests for InventoryService, NotificationService, and PaymentService by removing null content tests and adding instantiation checks.
2. Refactored KafkaMessageConsumerTest and KafkaMessageProducerTest to avoid requiring a real Kafka instance, focusing on class structure and method existence instead of integration behavior.
* Add microservices-messaging module and run scripts
Introduce the microservices-messaging module and register it in the root pom.xml. Add docker-compose.yml to run a local Kafka (confluentinc/cp-kafka) with a healthcheck, plus run-app.ps1 and run-app.sh helper scripts that start Kafka if needed and then launch the application. Update the module README with usage instructions. Also remove a duplicated junit-jupiter-api test dependency from the module pom to rely on project defaults.
* microservices-messaging: code style and Lombok
Add Lombok as a provided dependency and apply formatting/refactoring across the microservices-messaging module. Changes include import reordering, Javadoc and logging formatting, consistent lambda/try/catch indentation, small Kafka consumer/producer refinements (Duration/Properties usage and callback formatting), Message class tweaks (@Getter, JSON ctor and toString formatting) and EOF/newline fixes. Unit tests were also reformatted for consistency. These are non-functional style and readability improvements; no behavior changes intended.
* Make Kafka producer/consumer testable
Refactor KafkaMessageProducer and KafkaMessageConsumer to depend on the Producer/Consumer interfaces and add constructors that accept mockable instances. Extract default producer/consumer creation into factory methods so tests can inject MockProducer/MockConsumer. Update tests across the microservices-messaging module to use MockProducer/MockConsumer, add more meaningful assertions, error/interrupt handling tests, and simplify AppTest. These changes improve unit testability and remove the need for a running Kafka instance while preserving runtime behavior.
* Format test Javadoc and reorder imports
Normalize Javadoc formatting and reorder static JUnit imports for consistency in messaging tests. Converted multi-line test Javadocs to single-line comments and adjusted import ordering in the following files:
- microservices-messaging/src/test/java/com/iluwatar/messaging/KafkaMessageConsumerTest.java
- microservices-messaging/src/test/java/com/iluwatar/messaging/KafkaMessageProducerTest.java
- microservices-messaging/src/test/java/com/iluwatar/messaging/OrderServiceTest.java
No functional changes.
* Add MIT headers and exclude .ps1 from license checks
Add MIT license headers to microservices-messaging/docker-compose.yml, run-app.ps1 and run-app.sh to ensure license text is present in these scripts. Update root pom.xml to exclude PowerShell (*.ps1) files from the license plugin checks so those files are not processed by the license rule.
* Add Kafka docker service to CI workflows
Bring up Kafka for tests in CI and PR workflows. Adds steps to run docker compose for microservices-messaging, poll Kafka readiness (up to 20 retries), and always tear down with docker compose down. Enables Maven tests that depend on Kafka. Affects .github/workflows/maven-ci.yml and .github/workflows/maven-pr-builder.yml.
* Use kafka-topics instead of kafka-topics.sh
Replace calls to kafka-topics.sh with kafka-topics in CI workflows and the Docker Compose healthcheck. Updated .github/workflows/maven-ci.yml, .github/workflows/maven-pr-builder.yml, and microservices-messaging/docker-compose.yml to use the kafka-topics binary for readiness checks and healthchecks. This prevents failures on images that expose the kafka-topics command without the .sh wrapper.
* Use docker compose --wait for Kafka startup
Replace the custom bash readiness loop with `docker compose ... up -d --wait` in CI and PR workflows. This simplifies startup of the microservices-messaging Kafka service and removes the manual retry/polling logic. Files changed: .github/workflows/maven-ci.yml, .github/workflows/maven-pr-builder.yml. Note: requires a Docker Compose version that supports the `--wait` flag.
* Reformat tests for readability
Reformatted KafkaMessageConsumerTest and PaymentServiceTest for readability and consistent formatting: reflowed constructor invocation, expanded anonymous HashMap and schedulePollTask lambda blocks, and aligned assertDoesNotThrow parameters. These are pure style changes with no behavioral modifications.
* Remove Kafka Docker Compose steps from CI
Removed the Start/Stop Kafka Docker Service steps that ran docker compose for microservices-messaging from .github/workflows/maven-ci.yml and .github/workflows/maven-pr-builder.yml. Workflows no longer start or tear down the Kafka docker-compose service during CI/PR runs; other steps (xvfb install, Maven build, Codecov upload, Sonar cache) remain unchanged.
* Bump google-java-format to 1.27.0; tidy tests
Update pom.xml to use google-java-format 1.27.0 (was 1.17.0). Make minor formatting cleanups in KafkaMessageConsumerTest and PaymentServiceTest by collapsing multi-line calls into single lines. No functional changes.
* Downgrade Google Java Format to 1.17.0
Update Spotless googleJavaFormat version in root pom.xml from 1.27.0 to 1.17.0
* Improve Kafka producer and consumer tests
Enhance microservices-messaging tests: add consumer tests to verify run() exits immediately when stopped and gracefully handles a WakeupException (ensuring the MockConsumer is closed). Update producer error test to avoid try-with-resources, assert publish behavior and history, trigger failingProducer.errorNext(...) before closing to cover the error callback branch, then close and assert the mock producer is closed.
* Refactor App.run and add messaging tests
Extract App.run(...) and introduce a package-private sleepMs field to control sleep durations so the demo can be exercised programmatically and sped up for tests. Main now delegates to run; consumers are started there. Tests updated: AppTest sets sleepMs to 0 and adds testRunWithMockObjects using MockProducer/MockConsumer to exercise run without a Kafka broker; KafkaMessageProducerTest adds a null-message publish test; minor formatting fix in KafkaMessageConsumerTest. These changes improve testability and coverage for the microservices-messaging module.
* Add Backends For Frontends pattern (#300)
Implements the BFF pattern with two client-specific gateways
(MobileBff, DesktopBff) aggregating shared downstream services
(AuthService, CartService, OrderService, SupplierService) into
client-tailored response shapes.
Closes#300
* Rename SupplierService lookup key to productName for clarity
The service is looked up by product name throughout the codebase, not
an actual product ID as the previous naming implied.
* Address review feedback: remove unnecessary compact constructors, add InMemory* service tests
Add an educational rule-engine module demonstrating the Rule Engine
pattern. Each business rule is an independent object exposing evaluate
(decision) and execute (action); a RuleEngine evaluates a collection of
rules against an immutable loan-application context in insertion order,
runs the passing rules, and reports every passed and failed rule via an
immutable RuleEngineResult. Includes three concrete rules, an App demo,
unit tests, README, and class diagram.
* fix: V-002 security vulnerability
Automated security fix generated by Orbis Security AI
* adding cross-platform support
* fixing sonarqube hotspots
* fixing the formating for java windows
* fix: address PR review comments - Windows title bug, Unix paths, and consistency
- Add empty string title arg to cmd /c start to fix paths-with-spaces bug
- Revert Unix commands to bare names (open, xdg-open) with NOSONAR since
xdg-open location varies by distro; absolute paths broke portability
- Apply same ProcessBuilder fix to page-object/src App.java for consistency
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: resolve Windows path via SystemRoot env var instead of hardcoding
C:\Windows\System32\cmd.exe fails when Windows is installed on a
non-C drive. Use System.getenv("SystemRoot") with a C:\Windows
fallback to locate cmd.exe portably in both App.java files.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Update ved-asole link in .all-contributorsrc
Updated my profile link in .all-contributorsrc
* Update README.md with url for ved-asole profile
Update README.md with url for ved-asole profile
* feat: implement Immutable pattern #3448
Add immutable/ module with ImmutableUser (final class, defensive copy,
withAge wither method), App demo, JUnit 5 tests, PlantUML diagram, and
README following project conventions.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add withName and withRoles wither methods to ImmutableUser #3448
Every field now has a corresponding wither for consistency.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: add junit-jupiter-api dependency to immutable module #3448
Required for @Test annotations and assert methods in test code.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add STI tests
* test: add delta for floating-point comparison in VehicleServiceTest
* fix: guard teardown against nulls and use assertNotNull in VehicleServiceTest
Add null checks in @AfterEach tearDown() to prevent NullPointerException
if setUp() partially fails. Replace assertTrue(x != null) with assertNotNull(x).
* style: format code in SingleTableInheritanceTest and VehicleServiceTest for consistency
* docs: reformulate text, add links to further languages and paragraph about the book in central README.md
(#2275)
* docs: shorten text for link to payhip
(#2275)
* docs: reformulate german translation for Abstract Document
(#2275)
* Create folder for Abstract Factory
* Create README.md for Abstract Document
* Translate README.md for Abstract Document to German
* correct typo
* docs: add class diagrams for all patterns
(#2275)
* docs: add missing words in abstract-factory.README.md
(#2275)
* docs: Create German README.md for Active Object
#2275
first text part
* docs: finish German translation of README.md for Active Object
* docs: translate actor-model into German
#2295
* docs: add German translation for Acyclic Visitor
#2295
* correct typo
* docs: Translate Singleton into German
#2295
* docs: Translate Prototype into German
#2295
* Delete localization/de/Abstract Factory
* insert line break
* correct typos in actor-model
* realignment of java code block
* docs: translate Adapter Pattern into German
#2295
* Update README.md
change 'lizenz' to 'Lizenz' in badge
* Update README.md
translate 'benefits' and 'trade-offs'
* remove additional bullet point after line break
* correct indentation
* docs: translate Dependency Injection into German
#2295
* docs: translate Bridge into German
#2295
* correct typos
* docs: Translate Builder into German
* delete english text
* little changes in formulation
* Update README.md
change link to image
* docs: remove spanish files
(#2275)
* docs: remove non-translated patterns
(#2275)
* Create README.md
docs: Translate Step Builder into German
#2275
* Create README.md
docs: Translate Fluent Interface into German
#2275
* eager is eifrig, not gierig
* Translate Chain of Responsibility into German
#2275
* added new microservice pattern polling-publisher, created folder structure, README.md & App.java
* added two service polling service & publisher service to handle two different operation & prepared initial skeleton
* polling-publisher service implementation
* fixed checkstyle errors
* subscriber-service implementation
* added entry point for subscriber service & unit test-case
* added unit test-case for DataSourceService class
* resolved dependency & structured classes
* implemented Data repository, DataSource Service & added unittest-case & implemented polling-service microservice
* implemented subscriber microservice using kafkaConsumer
* Fixed Kafka bug & added a controller to send message using API
* Fixed subscriber-service & updated pom.xml
* Fixed topic name
* added new listener for other topic
* updated all README.md
* added description on both application.yaml file
* added scope before class definition in Test classes & removed duplicate dependency from pom.xml & added required one
* added polling-publisher module in pom.xml
* Updated README.md file based on new template
* improved the README.md file & fixed it's format
* deleted unnecessary README.md files
* fixed the printing statements & used log function
* used logger to print statement
* addressed review comment: removed unnecessary dependency
* addressed review comment
* need to fix one test case shouldGraduallyIncreaseLimitWhenHealthy failing for AdaptiveRateLimiter.java
* Added Class Diagram and Flow Diagrams for Adaptive, Fixed Window and Token Bucket Rate Limiter
* Updated README.md. All test case passed. Updated with Google Java Guidelines
* Updated parent pom #2973
* Updated parent pom #2973
* fixed shouldResetCounterAfterWindow() test #2973
* formatting fixed#2973
* added test coverage for app.java and fixed random to be thread safe #2973
* added test coverage for app.java and fixed random to be thread safe #2973
* added test coverage for app.java and fixed random to be thread safe #2973
* added test coverage for app.java and fixed random to be thread safe #2973
* added test coverage for app.java and fixed random to be thread safe #2973
* added test coverage for app.java and fixed random to be thread safe #2973
* added test coverage for app.java and fixed random to be thread safe #2973
* fixed random to be thread safe #2973
* fixed random to be thread safe #2973
* fixed random to be thread safe #2973
* fixed spacing in pom.xml #2973
---------
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
* #1263 - creating new module for view-helper
* #1263 - creating Product and ProductViewModel
* #1263 - creating interfaces for View and ViewHelper
* #1263 - creating ProductViewHelper and its test
* #1263 - creating Console View for Product
* #1263 - creating ProductController
* #1263 - creating main App and its test
* #1263 - adding license header
* #1263 - keeping module in alphabetical order
* #1263 - creating README and diagrams
* #1263 apply spotless
---------
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
* Persian Translation: Add persian translation to abstract-document
* Persian Translation: Add abstract-document.png to abstract-document folder
* Persian Translation: Add codes to README.md of abstract-document
* Persian Translation: some improvements in abstract-document
* Persian Translation: Add refrence links in abstract-document
* Persian Translation: add rtl tag in abstract-document
* -added persian translation of factory pattern
* -renamed file
* -changed wikipedia definition
* -fixed table problem
* active-object : translate
* active-object: improve when to use
* active-object: improve when to use
* active-object: improve bullets (test)
* active-object: improve bullets (test)
* active-object: improve bullets (test)
* active-object: improve bullets (test)
* active-object: improve bullets
* active-object: Fix all bullets
* -fixed problems in bullet alignments
* Update README.md
-fixed alignment in bullets
* Update README.md
-changed tags to English
* -added persian translation of factory pattern
* -renamed file
* -changed wikipedia definition
* -fixed table problem
* -fixed problems in bullet alignments
* Update README.md
-fixed alignment in bullets
* Update README.md
-changed tags to English
* abstract-factory: added persian translation
* abstract-factory: fixed bullets problems
* "Minor improvement
Co-authored-by: keivanshir <keivan.shir.74@gmail.com>"
---------
Co-authored-by: Seyyed Keivan Shirkoubian <keivan.shir.74@gmail.com>
* Services and information
* README.md updated
* unit tests added for controllers
* pom.xml, clean up, java version update and slf4j logging added
* pom files updated
* Removed children maven wrappers
* Microservice-self-registration added to pom file
* POM file updated for self-registration
* pom file updated
* Update pom.xml
correction to mudule name
* SonarQube comments addressed
* sonarqube comments on coverage addressed
* Code coverage for custom health checks
* changes for unit tests
* changes for unit tests
* changes to for code coverage improvement
- Add implementation of Thread-Pool Executor pattern using hotel front desk example
- Include unit tests
- Create detailed README with pattern explanation and examples
- Add Java source code with appropriate Javadoc comments
Closes#3226
* Persian Translation: Add persian translation to abstract-document
* Persian Translation: Add abstract-document.png to abstract-document folder
* Persian Translation: Add codes to README.md of abstract-document
* Persian Translation: some improvements in abstract-document
* Persian Translation: Add refrence links in abstract-document
* Persian Translation: add rtl tag in abstract-document
* active-object : translate
* active-object: improve when to use
* active-object: improve when to use
* active-object: improve bullets (test)
* active-object: improve bullets (test)
* active-object: improve bullets (test)
* active-object: improve bullets (test)
* active-object: improve bullets
* active-object: Fix all bullets
* -added persian translation of factory pattern
* -renamed file
* -changed wikipedia definition
* -fixed table problem
* -fixed problems in bullet alignments
* Update README.md
-fixed alignment in bullets
* Update README.md
-changed tags to English
---------
Co-authored-by: Seyyed Keivan Shirkoubian <keivan.shir.74@gmail.com>
* feat: Implement Actor Model pattern #3232
* feat: Implement Actor Model pattern #3232
* feat: update Actor Model implementation with multi-actor logic #3251
* feat: update Actor Model implementation with multi-actor logic and loose coupling #3251
* test: add unit test for actor model #3251
* test: add test for App.java to increase coverage
* docs: add complete README for Actor Model pattern also implemented changes #3251
* fix: handle awaitTermination result and ensure proper ExecutorService shutdown
- Added handling for the result of awaitTermination to avoid Sonar warning
- Wrapped ExecutorService with try-finally for proper shutdown (java:S2095)
- Prevents potential resource leak and aligns with best practices
Fixes: #2865
Note: ExecutorService is not AutoCloseable, so try-with-resources is not applicable. Used try-finally instead.
* fix: add missing logger definition for SLF4J
- Defined logger explicitly with LoggerFactory.getLogger(...)
- Ensured compatibility with Lombok's @Slf4j annotation
- Fixed compilation error caused by missing 'log' variable
* fix: add missing logger definition for SLF4J
* remove spring dep
move junit, logging, mockito under dep mgmt
* upgrade anti-corruption-layer deps
* async method invocation
* balking, bloc
* bridge to bytecode
* caching
* callback - cqrs
* component - health check
* hexagonal - metadata mapping
* rest of the patterns
* remove checkstyle, take spotless into use
* Add Service Stub Pattern using Sentiment Analysis example
* Fix Checkstyle issues
* Suppress Sonar warning for Random usage in RealSentimentAnalysisServer
* added a pom.xml file for the monolithic structure, set up MVC file structure, and added basic model files using H2 database since its light and efficient
* added a pom.xml file for the monolithic structure, set up MVC file structure, and added basic model files using H2 database since its light and efficient
* Added "controllers" and repository classes to communicate with database to maintain code cleanliness
* added application.properties file for springboot, added controller classes and used the CLI main class from the previous submission and enhanced upon it
* fixed checkstyle comments
* fixed testing class
* automatically generated puml
* Readme File
Added Detailed Readme File in the md format
* attempting to fix some debugging issues
added more test cases, and tried to fix pom.xml
* dropped change
* another attempted fix
* added more test cases
* Fixes
Renamed the main module/directory. Added more content to the readme.md file. fixed the orElseThrow statements
Fixes
Renamed the main module/directory. Added more content to the readme.md file. fixed the orElseThrow statements
* fixed naming and readme file
---------
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
* added bloC design pattern
* added bloC design pattern
* added Readme file
* fixed checkstyle warnings
* added tests for the ui
* fixed a test in MainTest file
* separating ui from main file and adding more tests
* added pom.xml plugins and properties and fixed readme.md
* fixed renaming problem and added context to main
* chsnged state class to record
* syncing changes for conflicts
* Revert "fixed conflicts"
* restored files
* renamed readme file and abstracted pom file
* Added Microservices client side ui composition to the repo.
Added ClientSideCompositionTest, ApiGateway, ClientSideIntegrator, FrontendComponent, CartFrontend, ProductFrontend, updated pom.xml, ReadME.md.
* Improved some checkstyle changes.
* Added Random variable to re-use the random instead of creating it everytime in FrontendComponent.
* changed the Pom.xml and upadted the ReadME.md
* Changes in the README.md File as per requirement, name of the file changed from ReadME.md to README.md
---------
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
* pattern:implemented the Template View pattern (#1320)
* fix:added links in README and updated package name (#1320)
---------
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
* Money pattern
the implementation of the money patter and the tests along with the read me file
* Update money/README.md
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
* added App file anf modified README file and pom.xml file
* modified README and pom.xml
* added comments
* Added a test for App.java
---------
Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
Title: Added a <title> element to provide a title for the page.
Enhanced Styling: Improved styling for readability and aesthetic appeal, including a background color and box shadow for the parameter section.
Expanded Descriptions: Clarified the purpose of each parameter.
Example Request: Provided an example of how to format a GET request.
Error Handling Tip: Included a note on what to do if the request fails.
* fix: add UnsupportedOperationException in KingsHand and GameLoopTest
* refactor: update DatabaseService to use constant for BINARY_DATA and remove obsolete test files
* refactor: update timePasses method in KingsHand
* refactor CandyGame.java
* refactor: simplify boundary checks in CandyGame
* feat: add getters for type and points in Candy class and initialize logger in CandyGame
* remove class and logger initialization in CandyGame
* Modify CandyGame.java
* fix Checkstyle violations
* Remove generic wildcard type in ThreatAwareSystem
* added idempotent consumer pattern
* updated doc
* fixed bug in RequestService
* add test converage
* Add test converage to state machine
* renamed module and added code example
* update yaml frontmatter format
* update abstract document
* update abstract factory
* use the new pattern template
* acyclic visitor seo
* adapter seo
* ambassador seo
* acl seo
* aaa seo
* async method invocation seo
* balking seo
* bridge seo
* builder seo
* business delegate and bytecode seo
* caching seo
* callback seo
* chain seo
* update headings
* circuit breaker seo
* client session + collecting parameter seo
* collection pipeline seo
* combinator SEO
* command seo
* cqrs seo
* commander seo
* component seo
* composite seo
* composite entity seo
* composite view seo
* context object seo
* converter seo
* crtp seo
* currying seo
* dao seo
* data bus seo
* data locality seo
* data mapper seo
* dto seo
* decorator seo
* delegation seo
* di seo
* dirty flag seo
* domain model seo
* double buffer seo
* double checked locking seo
* double dispatch seo
* dynamic proxy seo
* event aggregator seo
* event-based asynchronous seo
* eda seo
* event queue seo
* event sourcing seo
* execute around seo
* extension objects seo
* facade seo
* factory seo
* factory kit seo
* factory method seo
* fanout/fanin seo
* feature toggle seo
* filterer seo
* fluent interface seo
* flux seo
* flyweight seo
* front controller seo
* function composition seo
* game loop seo
* gateway seo
* guarded suspension seo
* half-sync/half-async seo
* health check seo
* hexagonal seo
* identity map seo
* intercepting filter seo
* interpreter seo
* iterator seo
* layers seo
* lazy loading seo
* leader election seo
* leader/followers seo
* lockable object seo
* rename and add seo for marker interface
* master-worker seo
* mediator seo
* memento seo
* metadata mapping seo
* microservice aggregator seo
* api gw seo
* microservices log aggregration seo
* mvc seo
* mvi seo
* mvp seo
* mvvm seo
* monad seo
* monitor seo
* monostate seo
* multiton seo
* mute idiom seo
* naked objects & notification seo
* null object seo
* object mother seo
* object pool seo
* observer seo
* optimistic locking seo
* page controller seo
* page object seo
* parameter object seo
* partial response seo
* pipeline seo
* poison pill seo
* presentation model seo
* private class data seo
* producer-consumer seo
* promise seo
* property seo
* prototype seo
* proxy seo
* queue-based load leveling seo
* reactor seo
* registry seo
* repository seo
* RAII seo
* retry seo
* role object seo
* saga seo
* separated interface seo
* serialized entity seo
* serialized lob seo
* servant seo
* server session seo
* service layer seo
* service locator seo
* service to worker seo
* sharding seo
* single table inheritance seo
* singleton seo
* spatial partition seo
* special case seo
* specification seo
* state seo
* step builder seo
* strangler seo
* strategy seo
* subclass sandbox seo
* table module seo
* template method seo
* throttling seo
* tolerant reader seo
* trampoline seo
* transaction script seo
* twin seo
* type object seo
* unit of work seo
* update method seo
* value object seo
* version number seo
* virtual proxy seo
* visitor seo
* seo enhancements
* seo improvements
* SEO enhancements
* SEO improvements
* SEO additions
* SEO improvements
* more SEO improvements
* rename hexagonal + SEO improvements
* SEO improvements
* more SEO stuff
* SEO improvements
* SEO optimizations
* SEO enhancements
* enchance SEO
* improve SEO
* SEO improvements
* update headers
* [Localization] (Add) Vietnamese translation of Builder pattern
* [Contributors] (Change) my link
Change my link in contributors list because it will expire soon
* Remove unused member which was also causing a false positive sonar issue.
Fixes sonar issue https://sonarcloud.io/project/issues?open=AY3gHwu5DIZTZkppqVEG&id=iluwatar_java-design-patterns
* Fixes sonar issue https://sonarcloud.io/project/issues?open=AXK0OzDA-CiGJS70dLki&id=iluwatar_java-design-patterns
related to "Refactor the code of the lambda to not have multiple invocations throwing the same checked exception."
Also, updated the code to use Instant and Duration to deal with time instead of int. Added the awaitility
library to perform assertions in test which is more reliable than using Thread.sleep directly to wait for events to happen.
* checkstyle fix
* Add sneaky throws to fix sonar lint issue. This is fine as the newFile method is not being tested but instead the new SimpleFileWriter(...) is.
* The first booking needs to happen outside the assertions. Fixed other warnings
* Use records to pass around related objects instead of using a large number of
individual params, which sonar did not like.
* Checkstyle fixes
* checkstyle fixes
* Remove complexity to keep sonar happy.
* Split into different methods to reduce complexity. Could be broken down even further but currently Sonar is happy.
* Move files to correct package
* Add valid assertions to tests
* rename constants to avoid confusion
* Sonar warning related to cognitive complexity can be suppressed as the methods are quite generic and not functional enough to be separated out.
* Use constants to keep Sonar happy
* Use correct constant naming conventions
* Use correct constant naming conventions
* Use lombok to define noargsconstructor
* Use a single method to do the logging
* Remove unused constructor and redundant method
* Use a reusable method for logging
* chore : upgrade the jackson-databind to latest version(2.17.0)
* refactor: refactor Composite View
* refactor: remove unnecessary chnges related to this PR(#2853)
* fix: checkstyle error in AppServlet.java
* Updated the imports in code of the single table inheritance pattern for Spring Boot 3.x
#2825
Change javax library to jakarta
* add pom.xml
* Updated the imports in code of the healthcheck pattern for SpringBoot 3.x
Change javax library to jakarta and update maven dependency versions
* change order of imports to pass Checkstyle violations
* change import order to pass lexicographical order test
* change import order to pass CustomImportOrder warning
* Updated the maven imports of layers pattern for SpringBoot 3.2.4
* remove unused maven import
* Updated the maven imports of api-gateway pattern for SpringBoot 3.2.4
#2822
* Flaky test in Thread Local Storage #2880
* Rollback testing changes
* Flaky test in Thread Local Storage #2880
Create independent threadLocal to make values unsharable and unchangable by other thread
* rollback branch conflict
* Updated the imports in code of the single table inheritance pattern for Spring Boot 3.x
#2825
Change javax library to jakarta
* add pom.xml
* Updated the imports in code of the healthcheck pattern for SpringBoot 3.x
Change javax library to jakarta and update maven dependency versions
* change order of imports to pass Checkstyle violations
* change import order to pass lexicographical order test
* change import order to pass CustomImportOrder warning
* Updated the maven imports of layers pattern for SpringBoot 3.2.4
* remove unused maven import
* Updated the maven imports of api-gateway pattern for SpringBoot 3.2.4
#2822
* Flaky test in Thread Local Storage #2880
* Rollback testing changes
* Updated the imports in code of the single table inheritance pattern for Spring Boot 3.x
#2825
Change javax library to jakarta
* add pom.xml
* Updated the imports in code of the healthcheck pattern for SpringBoot 3.x
Change javax library to jakarta and update maven dependency versions
* change order of imports to pass Checkstyle violations
* change import order to pass lexicographical order test
* change import order to pass CustomImportOrder warning
* Updated the maven imports of layers pattern for SpringBoot 3.2.4
* remove unused maven import
* Updated the maven imports of api-gateway pattern for SpringBoot 3.2.4
#2822
* Updated the maven imports of Aggregator Microservices pattern for SpringBoot 3.2.4
#2821
* Updated the imports in code of the single table inheritance pattern for Spring Boot 3.x
#2825
Change javax library to jakarta
* add pom.xml
* Updated the imports in code of the healthcheck pattern for SpringBoot 3.x
Change javax library to jakarta and update maven dependency versions
* change order of imports to pass Checkstyle violations
* change import order to pass lexicographical order test
* change import order to pass CustomImportOrder warning
* Updated the maven imports of layers pattern for SpringBoot 3.2.4
* remove unused maven import
* Updated the maven imports of page-controller pattern for SpringBoot 3.2.4
- add page-controller module on parent pom.xml
- add artifact information on page-controller pom.xml
- add Springboot3, proper test dependencies on page-controller pom.xml
* Updated the imports in code of the single table inheritance pattern for Spring Boot 3.x
#2825
Change javax library to jakarta
* add pom.xml
* Updated the imports in code of the healthcheck pattern for SpringBoot 3.x
Change javax library to jakarta and update maven dependency versions
* change order of imports to pass Checkstyle violations
* change import order to pass lexicographical order test
* change import order to pass CustomImportOrder warning
* Updated the maven imports of layers pattern for SpringBoot 3.2.4
* remove unused maven import
* Updated the imports in code of the single table inheritance pattern for Spring Boot 3.x
#2825
Change javax library to jakarta
* add pom.xml
* Updated the imports in code of the healthcheck pattern for SpringBoot 3.x
Change javax library to jakarta and update maven dependency versions
* change order of imports to pass Checkstyle violations
* change import order to pass lexicographical order test
* change import order to pass CustomImportOrder warning
* translation: translation of observer pattern to Italian
* translation: translation of observer pattern to Italian - pattern name corrected
---------
Co-authored-by: Leonardo Lisanti <leonardo_lisanti@epam.com>
* implemented single table inheritance
* added the Java documentation for the pattern
* updated code files as per the standards
* added the puml and png diagram for the file
* added README.md
* #1316 Single Table Inheritance pattern implemented
* resolved the Checkstyle violations
* removed the tests due to build failure
* updated the code as per review
* resolved Checkstyle violations
* translation for step-builder and table-module and unit-of-work and update-method and value-object to Chinese
* fix a translation error
* Add explanation for guarded suspension
* delete previous modifications
* translate Abstract Document documentation in french
* translate Abstract Document documentation in french for issue #2278
* french translation of abstract factory
* French translation for active-object
* translate Abstract Document documentation in french
* translate Abstract Document documentation in french for issue #2278
* french translation of abstract factory
* French translation for active-object
* tranlate to french: acyclic-visitore, adapter, aggregator-microservice, ambassador, api-gateway, arrange-act-assert, async-method-invocation, balking, bridge.
-`/pom.xml`: The root Maven configuration file that defines global dependencies and lists all pattern modules.
-`/[pattern-name]/`: Individual folders for each design pattern (e.g., `/abstract-factory`, `/builder`), acting as standalone Maven modules.
-`/[pattern-name]/src/main/java/`: Contains the actual Java implementation classes of the specific design pattern.
-`/[pattern-name]/src/test/java/`: Contains the JUnit tests verifying the pattern's behavior.
-`/[pattern-name]/README.md`: The documentation for the pattern, which gets published to the main website.
## Patterns
- Keep pattern implementations simple, atomic, and easy to understand.
- Write descriptive and meaningful names for classes, interfaces, and methods.
- Always include comprehensive unit tests for every new pattern or code modification.
- Follow the Google Java Format strictly (enforced by Spotless).
- Document the intent, explanation, and real-world usage clearly in each module's `README.md`.
## Anti-patterns
- Avoid overcomplicating patterns with unnecessary external dependencies or complex frameworks.
- Do not introduce business logic that distracts from the core mechanism of the design pattern itself.
- Submitting new patterns or features without corresponding unit tests is strictly discouraged.
- Avoid large monolithic packages; each pattern should reside in its own isolated module.
## Example Design Pattern
When a new design pattern is added to the repository, it generally follows these steps:
- **Create a Module**: Create a new folder for the pattern in the root directory (e.g., `/my-new-pattern`).
- **Update root pom.xml**: Add `<module>my-new-pattern</module>` to the `<modules>` section of the root `pom.xml`.
- **Add Module pom.xml**: Create a `pom.xml` inside the new folder that inherits from the parent project.
- **Write the Code**: Implement the pattern logic under `src/main/java/com/iluwatar/mynewpattern`, usually including an `App.java` class to demonstrate its usage.
- **Write the Tests**: Add comprehensive unit tests under `src/test/java/com/iluwatar/mynewpattern`.
- **Document**: Create a `README.md` at the root of the new module, structured with standard sections like Intent, Explanation, Class diagram, Applicability, and Real world examples.
[](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)
[](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
Design patterns are the best, formalized practices a programmer can use to
solve common problems when designing an application or system.
Design patterns are the best, formalized practices a programmer can use to solve common problems when designing an application or system.
Design patterns can speed up the development process by providing tested, proven
development paradigms.
Design patterns can speed up the development process by providing tested, proven development paradigms.
Reusing design patterns help prevent subtle issues that cause major
problems, and it also improves code readability for coders and architects who
are familiar with the patterns.
Reusing design patterns helps prevent subtle issues that cause major problems, and it also improves code readability for coders and architects who are familiar with the patterns.
# Getting started
# Getting Started
This site showcases Java Design Patterns. The solutions have been developed by
experienced programmers and architects from the open-source community. The
patterns can be browsed by their high-level descriptions or by looking at their
source code. The source code examples are well commented and can be thought of as
programming tutorials on how to implement a specific pattern. We use the most
popular battle-proven open-source Java technologies.
This site showcases Java Design Patterns. The solutions have been developed by experienced programmers and architects from the open-source community. The patterns can be browsed by their high-level descriptions or by looking at their
source code. The source code examples are well commented and can be thought of as programming tutorials on how to implement a specific pattern. We use the most popular battle-proven open-source Java technologies.
Before you dive into the material, you should be familiar with various
Before you dive into the material, you should be familiar with various [Software Design Principles](https://java-design-patterns.com/principles/).
All designs should be as simple as possible. You should start with KISS, YAGNI,
and Do The Simplest Thing That Could Possibly Work principles. Complexity and
patterns should only be introduced when they are needed for practical
extensibility.
All designs should be as simple as possible. You should start with KISS, YAGNI, and Do The Simplest Thing That Could Possibly Work principles. Complexity and patterns should only be introduced when they are needed for practical extensibility.
Once you are familiar with these concepts you can start drilling down into the
[available design patterns](https://java-design-patterns.com/patterns/) by any
of the following approaches
Once you are familiar with these concepts you can start drilling down into the [available design patterns](https://java-design-patterns.com/patterns/) by any of the following approaches:
- Search for a specific pattern by name. Can't find one? Please report a new pattern [here](https://github.com/iluwatar/java-design-patterns/issues).
- Using tags such as `Performance`, `Gang of Four` or `Data access`.
- Using pattern categories, `Creational`, `Behavioral`, and others.
Hopefully, you find the object-oriented solutions presented on this site useful
in your architectures and have as much fun learning them as we had while developing them.
Hopefully, you find the object-oriented solutions presented on this site useful in your architectures and have as much fun learning them as we had while developing them.
# How to contribute
# How to Contribute
If you are willing to contribute to the project you will find the relevant information in
our [developer wiki](https://github.com/iluwatar/java-design-patterns/wiki). We will help
you and answer your questions in the [Gitter chatroom](https://gitter.im/iluwatar/java-design-patterns).
If you are willing to contribute to the project you will find the relevant information in our [developer wiki](https://github.com/iluwatar/java-design-patterns/wiki). We will help you and answer your questions in the [Gitter chatroom](https://gitter.im/iluwatar/java-design-patterns).
# The Book
The design patterns are now available as an e-book. Find out more about "Open Source Java Design Patterns" here: https://payhip.com/b/bNQFX
The project contributors can get the book for free. Contact the maintainer via [Gitter chatroom](https://gitter.im/iluwatar/java-design-patterns) or email (iluwatar (at) gmail (dot) com ). Send a message that contains your email address, Github username, and a link to an accepted pull request.
# License
This project is licensed under the terms of the MIT license.
<p>SerpApi is the world’s leading provider of search data, pioneering APIs that turn search engine results into structured, developer-ready information.</p>
</td>
</tr>
</table>
# Contributors
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
@@ -76,407 +82,562 @@ This project is licensed under the terms of the MIT license.
title: "Abstract Document Pattern in Java: Simplifying Data Handling with Flexibility"
shortTitle: Abstract Document
description: "Explore the Abstract Document design pattern in Java. Learn its intent, explanation, applicability, benefits, and see real-world examples to implement flexible and dynamic data structures."
category: Structural
language: en
tag:
- Abstraction
- Decoupling
- Dynamic typing
- Encapsulation
- Extensibility
- Polymorphism
---
## Intent
## Intent of Abstract Document Design Pattern
The "Abstract Document" design pattern is a structural design pattern that aims to provide a consistent way to handle
hierarchical and tree-like data structures by defining a common interface for various document types.
The Abstract Document design pattern in Java is a crucial structural design pattern that provides a consistent way to handle hierarchical and tree-like data structures by defining a common interface for various document types. It separates the core document structure from specific data formats, enabling dynamic updates and simplified maintenance.
## Explanation
## Detailed Explanation of Abstract Document Pattern with Real-World Examples
The Abstract Document pattern enables handling additional, non-static properties. This pattern
uses concept of traits to enable type safety and separate properties of different classes into
set of interfaces.
The Abstract Document design pattern in Java allows dynamic handling of non-static properties. This pattern uses concept of traits to enable type safety and separate properties of different classes into set of interfaces.
Realworld example
Real-world example
> Consider a car that consists of multiple parts. However, we don't know if the specific car really has all the parts, or just some of them. Our cars are dynamic and extremely flexible.
> Consider a library system implementing the Abstract Document design pattern in Java, where books can have diverse formats and attributes: physical books, eBooks, and audiobooks. Each format has unique properties, such as page count for physical books, file size for eBooks, and duration for audiobooks. The Abstract Document design pattern allows the library system to manage these diverse formats flexibly. By using this pattern, the system can store and retrieve properties dynamically, without needing a rigid structure for each book type, making it easier to add new formats or attributes in the future without significant changes to the codebase.
In plain words
@@ -27,16 +31,18 @@ In plain words
Wikipedia says
> An object-oriented structural design pattern for organizing objects in loosely typed key-value stores and exposing
the data using typed views. The purpose of the pattern is to achieve a high degree of flexibility between components
in a strongly typed language where new properties can be added to the object-tree on the fly, without losing the
support of type-safety. The pattern makes use of traits to separate different properties of a class into different
interfaces.
> An object-oriented structural design pattern for organizing objects in loosely typed key-value stores and exposing the data using typed views. The purpose of the pattern is to achieve a high degree of flexibility between components in a strongly typed language where new properties can be added to the object-tree on the fly, without losing the support of type-safety. The pattern makes use of traits to separate different properties of a class into different interfaces.
**Programmatic Example**
Class diagram
Let's first define the base classes `Document` and `AbstractDocument`. They basically make the object hold a property
map and any amount of child objects.

## Programmatic Example of Abstract Document Pattern in Java
Consider a car that consists of multiple parts. However, we don't know if the specific car really has all the parts, or just some of them. Our cars are dynamic and extremely flexible.
Let's first define the base classes `Document` and `AbstractDocument`. They basically make the object hold a property map and any amount of child objects.
```java
public interface Document {
@@ -78,11 +84,12 @@ public abstract class AbstractDocument implements Document {
.flatMap(Collection::stream)
.map(constructor);
}
...
// Other properties and methods...
}
```
Next we define an enum `Property` and a set of interfaces for type, price, model and parts. This allows us to create
static looking interface to our `Car` class.
Next we define an enum `Property` and a set of interfaces for type, price, model and parts. This allows us to create static looking interface to our `Car` class.
```java
public enum Property {
@@ -103,6 +110,7 @@ public interface HasPrice extends Document {
public class Part extends AbstractDocument implements HasType, HasModel, HasPrice {
public Part(Map<String, Object> properties) {
super(properties);
}
}
```
Now we are ready to introduce the `Car`.
@@ -132,6 +147,7 @@ public class Car extends AbstractDocument implements HasModel, HasPrice, HasPart
And finally here's how we construct and use the `Car` in a full example.
```java
public static void main(String[] args) {
LOGGER.info("Constructing parts and car");
var wheelProperties = Map.of(
@@ -160,25 +176,24 @@ And finally here's how we construct and use the `Car` in a full example.
p.getModel().orElse(null),
p.getPrice().orElse(null))
);
// Constructing parts and car
// Here is our car:
// model: 300SL
// price: 10000
// parts:
// wheel/15C/100
// door/Lambo/300
}
```
## Class diagram
The program output:

```
07:21:57.391 [main] INFO com.iluwatar.abstractdocument.App -- Constructing parts and car
07:21:57.393 [main] INFO com.iluwatar.abstractdocument.App -- Here is our car:
07:21:57.393 [main] INFO com.iluwatar.abstractdocument.App -- -> model: 300SL
07:21:57.394 [main] INFO com.iluwatar.abstractdocument.App -- -> price: 10000
07:21:57.394 [main] INFO com.iluwatar.abstractdocument.App -- -> parts:
07:21:57.395 [main] INFO com.iluwatar.abstractdocument.App -- wheel/15C/100
07:21:57.395 [main] INFO com.iluwatar.abstractdocument.App -- door/Lambo/300
```
## Applicability
## When to Use the Abstract Document Pattern in Java
This pattern is particularly useful in scenarios where you have different types of documents that share some common
attributes or behaviors, but also have unique attributes or behaviors specific to their individual types. Here are
some scenarios where the Abstract Document design pattern can be applicable:
The Abstract Document design pattern is especially beneficial in scenarios requiring management of different document types in Java that share some common attributes or behaviors, but also have unique attributes or behaviors specific to their individual types. Here are some scenarios where the Abstract Document design pattern can be applicable:
* Content Management Systems (CMS): In a CMS, you might have various types of content such as articles, images, videos, etc. Each type of content could have shared attributes like creation date, author, and tags, while also having specific attributes like image dimensions for images or video duration for videos.
@@ -194,13 +209,39 @@ some scenarios where the Abstract Document design pattern can be applicable:
* Project Management Tools: In project management applications, you could have different types of tasks like to-do items, milestones, and issues. The Abstract Document pattern could be used to handle general attributes like task name and assignee, while allowing for specific attributes like milestone date or issue priority.
The key idea behind the Abstract Document design pattern is to provide a flexible and extensible way to manage different
types of documents or entities with shared and distinct attributes. By defining a common interface and implementing it
across various document types, you can achieve a more organized and consistent approach to handling complex data
structures.
* Documents have diverse and evolving attribute structures.
## Credits
* Dynamically adding new properties is a common requirement.
* [Martin Fowler: Dealing with properties](http://martinfowler.com/apsupp/properties.pdf)
* [Pattern-Oriented Software Architecture Volume 4: A Pattern Language for Distributed Computing (v. 4)](https://www.amazon.com/gp/product/0470059028/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0470059028&linkId=e3aacaea7017258acf184f9f3283b492)
* Decoupling data access from specific formats is crucial.
* Maintainability and flexibility are critical for the codebase.
The key idea behind the Abstract Document design pattern is to provide a flexible and extensible way to manage different types of documents or entities with shared and distinct attributes. By defining a common interface and implementing it across various document types, you can achieve a more organized and consistent approach to handling complex data structures.
## Benefits and Trade-offs of Abstract Document Pattern
Benefits:
* Flexibility: Accommodates varied document structures and properties.
* Extensibility: Dynamically add new attributes without breaking existing code.
* Maintainability: Promotes clean and adaptable code due to separation of concerns.
* Reusability: Typed views enable code reuse for accessing specific attribute types.
Trade-offs:
* Complexity: Requires defining interfaces and views, adding implementation overhead.
* Performance: Might introduce slight performance overhead compared to direct data access.
## References and Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI)
* [Java Design Patterns: A Hands-On Experience with Real-World Examples](https://amzn.to/3yhh525)
* [Pattern-Oriented Software Architecture Volume 4: A Pattern Language for Distributed Computing (v. 4)](https://amzn.to/49zRP4R)
* [Patterns of Enterprise Application Architecture](https://amzn.to/3WfKBPR)
title: "Abstract Factory Pattern in Java: Mastering Object Creation Elegantly"
shortTitle: Abstract Factory
description: "Learn the Abstract Factory pattern in Java with real-world examples, class diagrams, and tutorials. Understand its intent, applicability, benefits, and known uses to enhance your design pattern knowledge."
category: Creational
language: en
tag:
- Abstraction
- Decoupling
- Gang of Four
- Instantiation
- Polymorphism
---
## Also known as
Kit
* Kit
## Intent
## Intent of Abstract Factory Design Pattern
Provide an interface for creating families of related or dependent
objects without specifying their concrete classes.
The Abstract Factory pattern in Java provides an interface for creating families of related or dependent objects without specifying their concrete classes, enhancing modularity and flexibility in software design.
## Explanation
## Detailed Explanation of Abstract Factory Pattern with Real-World Examples
Real-world example
> To create a kingdom we need objects with a common theme. The elven kingdom needs an elven king, elven castle, and elven army whereas the orcish kingdom needs an orcish king, orcish castle, and orcish army. There is a dependency between the objects in the kingdom.
> Imagine a furniture company that uses the Abstract Factory pattern in Java to produce various styles of furniture: modern, Victorian, and rustic. Each style includes products like chairs, tables, and sofas. To ensure consistency within each style, the company uses an Abstract Factory pattern.
>
> In this scenario, the Abstract Factory is an interface for creating families of related furniture objects (chairs, tables, sofas). Each concrete factory (ModernFurnitureFactory, VictorianFurnitureFactory, RusticFurnitureFactory) implements the Abstract Factory interface and creates a set of products that match the specific style. This way, clients can create a whole set of modern or Victorian furniture without worrying about the details of their instantiation. This maintains a consistent style and allows easy swapping of one style of furniture for another.
In plain words
@@ -29,10 +36,15 @@ Wikipedia says
> The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes
**Programmatic Example**
Class diagram
Translating the kingdom example above. First of all, we have some interfaces and implementation for the objects in the
kingdom.

## Programmatic Example of Abstract Factory in Java
To create a kingdom using the Abstract Factory pattern in Java, we need objects with a common theme. The elven kingdom needs an elven king, elven castle, and elven army whereas the orcish kingdom needs an orcish king, orcish castle, and orcish army. There is a dependency between the objects in the kingdom.
Translating the kingdom example above. First of all, we have some interfaces and implementation for the objects in the kingdom.
```java
public interface Castle {
@@ -50,20 +62,25 @@ public interface Army {
// Elven implementations ->
public class ElfCastle implements Castle {
static final String DESCRIPTION = "This is the elven castle!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class ElfKing implements King {
static final String DESCRIPTION = "This is the elven king!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class ElfArmy implements Army {
static final String DESCRIPTION = "This is the elven Army!";
@Override
public String getDescription() {
return DESCRIPTION;
@@ -71,7 +88,6 @@ public class ElfArmy implements Army {
}
// Orcish implementations similarly -> ...
```
Then we have the abstraction and implementations for the kingdom factory.
@@ -79,7 +95,9 @@ Then we have the abstraction and implementations for the kingdom factory.
```java
public interface KingdomFactory {
Castle createCastle();
King createKing();
Army createArmy();
}
@@ -101,49 +119,10 @@ public class ElfKingdomFactory implements KingdomFactory {
}
}
public class OrcKingdomFactory implements KingdomFactory {
@Override
public Castle createCastle() {
return new OrcCastle();
}
@Override
public King createKing() {
return new OrcKing();
}
@Override
public Army createArmy() {
return new OrcArmy();
}
}
// Orcish implementations similarly -> ...
```
Now we have the abstract factory that lets us make a family of related objects i.e. elven kingdom factory creates elven castle, king and army, etc.
```java
var factory = new ElfKingdomFactory();
var castle = factory.createCastle();
var king = factory.createKing();
var army = factory.createArmy();
castle.getDescription();
king.getDescription();
army.getDescription();
```
Program output:
```java
This is the elven castle!
This is the elven king!
This is the elven Army!
```
Now, we can design a factory for our different kingdom factories. In this example, we created `FactoryMaker`, responsible for returning an instance of either `ElfKingdomFactory` or `OrcKingdomFactory`.
The client can use `FactoryMaker` to create the desired concrete factory which, in turn, will produce different concrete objects (derived from `Army`, `King`, `Castle`).
In this example, we also used an enum to parameterize which type of kingdom factory the client will ask for.
Now, we can design a factory for our different kingdom factories. In this example, we created `FactoryMaker`, responsible for returning an instance of either `ElfKingdomFactory` or `OrcKingdomFactory`. The client can use `FactoryMaker` to create the desired concrete factory which, in turn, will produce different concrete objects (derived from `Army`, `King`, `Castle`). In this example, we also used an enum to parameterize which type of kingdom factory the client will ask for.
```java
public static class FactoryMaker {
@@ -156,74 +135,93 @@ public static class FactoryMaker {
return switch (type) {
case ELF -> new ElfKingdomFactory();
case ORC -> new OrcKingdomFactory();
default -> throw new IllegalArgumentException("KingdomType not supported.");
* [Singleton](https://java-design-patterns.com/patterns/singleton/): Abstract Factory classes are often implemented as Singletons.
* [Factory Kit](https://java-design-patterns.com/patterns/factory-kit/): Similar to Abstract Factory but focuses on configuring and managing a set of related objects in a flexible way.
## Credits
## References and Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI)
* [Design Patterns in Java](https://amzn.to/3Syw0vC)
* [Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software](https://amzn.to/49NGldq)
* [Java Design Patterns: A Hands-On Experience with Real-World Examples](https://amzn.to/3HWNf4U)
title: "Active Object Pattern in Java: Achieving Efficient Asynchronous Processing"
shortTitle: Active Object
description: "Learn about the Active Object design pattern in Java. This guide covers asynchronous behavior, concurrency, and practical examples to enhance your Java applications' performance."
category: Concurrency
language: en
tag:
- Performance
- Asynchronous
- Decoupling
- Messaging
- Synchronization
- Thread management
---
## Intent of Active Object Design Pattern
## Intent
The active object design pattern decouples method execution from method invocation for objects that each reside in their thread of control. The goal is to introduce concurrency, by using asynchronous method invocation, and a scheduler for handling requests.
The Active Object pattern provides a reliable method for asynchronous processing in Java, ensuring responsive applications and efficient thread management. It achieves this by encapsulating tasks within objects that have their own thread and message queue. This separation keeps the main thread responsive and avoids issues like direct thread manipulation or shared state access.
## Explanation
The class that implements the active object pattern will contain a self-synchronization mechanism without using 'synchronized' methods.
## Detailed Explanation of Active Object Pattern with Real-World Examples
Real-world example
>The Orcs are known for their wildness and untameable soul. It seems like they have their own thread of control based on previous behavior.
> Imagine a busy restaurant where customers place orders with waiters. Instead of the waiters going to the kitchen to prepare the food themselves, they write the orders on slips and hand them to a dispatcher. The dispatcher manages a pool of chefs who prepare the meals asynchronously. Once a chef is free, they pick up the next order from the queue, prepare the dish, and notify the waiter when it's ready for serving.
>
> In this analogy, the waiters represent the client threads, the dispatcher represents the scheduler, and the chefs represent the method execution in separate threads. This setup allows the waiters to continue taking orders without being blocked by the food preparation process, much like the Active Object pattern decouples method invocation from execution to enhance concurrency.
To implement a creature that has its own thread of control mechanism and expose its API only and not the execution itself, we can use the Active Object pattern.
In plain words
> The Active Object pattern decouples method execution from method invocation to improve concurrency and responsiveness in multithreaded applications.
Wikipedia says
> The active object design pattern decouples method execution from method invocation for objects that each reside in their own thread of control.[1] The goal is to introduce concurrency, by using asynchronous method invocation and a scheduler for handling requests.
>
> The pattern consists of six elements:
>
> * A proxy, which provides an interface towards clients with publicly accessible methods.
> * An interface which defines the method request on an active object.
> * A list of pending requests from clients.
> * A scheduler, which decides which request to execute next.
> * The implementation of the active object method.
> * A callback or variable for the client to receive the result.
This section explains how the Active Object design pattern works in Java, highlighting its use in asynchronous task management and concurrency control.
The Orcs are known for their wildness and untameable soul. It seems like they have their own thread of control based on previous behavior. To implement a creature that has its own thread of control mechanism and expose its API only and not the execution itself, we can use the Active Object pattern.
```java
public abstract class ActiveCreature{
public abstract class ActiveCreature{
private final Logger logger = LoggerFactory.getLogger(ActiveCreature.class.getName());
private BlockingQueue<Runnable> requests;
@@ -56,8 +85,8 @@ public abstract class ActiveCreature{
requests.put(new Runnable() {
@Override
public void run() {
logger.info("{} is eating!",name());
logger.info("{} has finished eating!",name());
logger.info("{} is eating!",name());
logger.info("{} has finished eating!",name());
}
}
);
@@ -67,7 +96,7 @@ public abstract class ActiveCreature{
requests.put(new Runnable() {
@Override
public void run() {
logger.info("{} has started to roam the wastelands.",name());
logger.info("{} has started to roam the wastelands.",name());
}
}
);
@@ -79,9 +108,9 @@ public abstract class ActiveCreature{
}
```
We can see that any class that will extend the ActiveCreature class will have its own thread of control to invoke and execute methods.
We can see that any class that will extend the `ActiveCreature` class will have its own thread of control to invoke and execute methods.
For example, the Orc class:
For example, the `Orc` class:
```java
public class Orc extends ActiveCreature {
@@ -89,13 +118,18 @@ public class Orc extends ActiveCreature {
public Orc(String name) {
super(name);
}
}
```
Now, we can create multiple creatures such as Orcs, tell them to eat and roam, and they will execute it on their own thread of control:
Now, we can create multiple creatures such as orcs, tell them to eat and roam, and they will execute it on their own thread of control:
```java
public class App implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(App.class.getName());
private static final int NUM_CREATURES = 3;
public static void main(String[] args) {
var app = new App();
app.run();
@@ -103,25 +137,86 @@ Now, we can create multiple creatures such as Orcs, tell them to eat and roam, a
@Override
public void run() {
ActiveCreature creature;
List<ActiveCreature> creatures = new ArrayList<>();
try {
for (int i = 0;i < creatures;i++) {
creature = new Orc(Orc.class.getSimpleName().toString() + i);

```
09:00:02.501 [Thread-0] INFO com.iluwatar.activeobject.ActiveCreature -- Orc0 is eating!
09:00:02.501 [Thread-2] INFO com.iluwatar.activeobject.ActiveCreature -- Orc2 is eating!
09:00:02.501 [Thread-1] INFO com.iluwatar.activeobject.ActiveCreature -- Orc1 is eating!
09:00:02.504 [Thread-0] INFO com.iluwatar.activeobject.ActiveCreature -- Orc0 has finished eating!
09:00:02.504 [Thread-1] INFO com.iluwatar.activeobject.ActiveCreature -- Orc1 has finished eating!
09:00:02.504 [Thread-0] INFO com.iluwatar.activeobject.ActiveCreature -- Orc0 has started to roam in the wastelands.
09:00:02.504 [Thread-2] INFO com.iluwatar.activeobject.ActiveCreature -- Orc2 has finished eating!
09:00:02.504 [Thread-1] INFO com.iluwatar.activeobject.ActiveCreature -- Orc1 has started to roam in the wastelands.
09:00:02.504 [Thread-2] INFO com.iluwatar.activeobject.ActiveCreature -- Orc2 has started to roam in the wastelands.
```
## Tutorials
## When to Use the Active Object Pattern in Java
* [Android and Java Concurrency: The Active Object Pattern](https://www.youtube.com/watch?v=Cd8t2u5Qmvc)
Use the Active Object pattern in Java when:
* when you need to handle asynchronous tasks without blocking the main thread, ensuring better performance and responsiveness.
* When you need to interact with external resources asynchronously.
* When you want to improve the responsiveness of your application.
* When you need to manage concurrent tasks in a modular and maintainable way.
## Active Object Pattern Java Tutorials
* [Android and Java Concurrency: The Active Object Pattern(Douglas Schmidt)](https://www.youtube.com/watch?v=Cd8t2u5Qmvc)
## Real-World Applications of Active Object Pattern in Java
* Real-time trading systems where transaction requests are handled asynchronously.
* GUIs where long-running tasks are executed in the background without freezing the user interface.
* Game programming to handle concurrent updates to game state or AI computations.
## Benefits and Trade-offs of Active Object Pattern
Discover the benefits and trade-offs of using the Active Object pattern in Java, including improved thread safety and potential overhead concerns.
Benefits:
* Improves responsiveness of the main thread.
* Encapsulates concurrency concerns within objects.
* Promotes better code organization and maintainability.
* Provides thread safety and avoids shared state access problems.
Trade-offs:
* Introduces additional overhead due to message passing and thread management.
* May not be suitable for all types of concurrency problems.
## Related Java Design Patterns
* [Command](https://java-design-patterns.com/patterns/command/): Encapsulates a request as an object, similarly to how the Active Object pattern encapsulates method calls.
* [Promise](https://java-design-patterns.com/patterns/promise/): Provides a means to retrieve the result of an asynchronous method call, often used in conjunction with Active Object.
* [Proxy](https://java-design-patterns.com/patterns/proxy/): The Active Object pattern can use a proxy to handle method invocations asynchronously.
## References and Credits
* [Design Patterns: Elements of Reusable Object Software](https://amzn.to/3HYqrBE)
* [Concurrent Programming in Java: Design Principles and Patterns](https://amzn.to/498SRVq)
* [Java Concurrency in Practice](https://amzn.to/4aRMruW)
* [Learning Concurrent Programming in Scala](https://amzn.to/3UE07nV)
* [Pattern Languages of Program Design 3](https://amzn.to/3OI1j61)
* [Pattern-Oriented Software Architecture Volume 2: Patterns for Concurrent and Networked Objects](https://amzn.to/3UgC24V)
title: "Actor Model Pattern in Java: Building Concurrent Systems with Elegance"
shortTitle: Actor Model
description: "Explore the Actor Model pattern in Java with real-world examples and practical implementation. Learn how to build scalable, message-driven systems using actors, messages, and asynchronous communication."
category: Concurrency
language: en
tag:
- Concurrency
- Messaging
- Isolation
- Asynchronous
- Distributed Systems
- Actor Model
---
## Also Known As
- Message-passing concurrency
- Actor-based concurrency
---
## Intent of Actor Model Pattern
The Actor Model pattern enables the construction of highly concurrent, distributed, and fault-tolerant systems by using isolated components (actors) that interact exclusively through asynchronous message passing.
---
## Detailed Explanation of Actor Model Pattern with Real-World Examples
### 📦 Real-world Example
Imagine a customer service system:
- Each **customer support agent** is an **actor**.
- Customers **send questions (messages)** to agents.
- Each agent handles one request at a time and can **respond asynchronously** without interfering with other agents.
---
### 🧠 In Plain Words
> "Actors are like independent workers that never share memory and only communicate through messages."
---
### 📖 Wikipedia Says
> [Actor model](https://en.wikipedia.org/wiki/Actor_model) is a mathematical model of concurrent computation that treats "actors" as the universal primitives of concurrent computation.
---
### 🧹 Architecture Diagram

---
## Programmatic Example of Actor Model Pattern in Java
### Actor.java
```java
public abstract class Actor implements Runnable {
@Setter@Getter private String actorId;
private final BlockingQueue<Message> mailbox = new LinkedBlockingQueue<>();
title: "Acyclic Visitor Pattern in Java: Streamlining Object Interactions"
shortTitle: Acyclic Visitor
description: "Learn about the Acyclic Visitor pattern in Java. This guide explains how it decouples operations from object hierarchies, providing examples and real-world applications."
category: Behavioral
language: en
tag:
- Decoupling
- Extensibility
- Interface
- Object composition
---
## Intent
## Intent of Acyclic Visitor Design Pattern
Allow new functions to be added to existing class hierarchies without affecting those hierarchies, and without creating
the troublesome dependency cycles that are inherent to the GoF Visitor Pattern.
The Acyclic Visitor pattern in Java decouples operations from an object hierarchy, providing a flexible design for various applications.
## Explanation
## Detailed Explanation of Acyclic Visitor Pattern with Real-World Examples
Realworld example
Real-world example
> We have a hierarchy of modem classes. The modems in this hierarchy need to be visited by an external algorithm based
> on filtering criteria (is it Unix or DOS compatible modem).
> An analogous real-world example of the Acyclic Visitor pattern in Java is a museum guide system, demonstrating the practical application of this design pattern. Imagine a museum with various exhibits like paintings, sculptures, and historical artifacts. The museum has different types of guides (audio guide, human guide, virtual reality guide) that provide information about each exhibit. Instead of modifying the exhibits every time a new guide type is introduced, each guide implements an interface to visit different exhibit types. This way, the museum can add new types of guides without altering the existing exhibits, ensuring that the system remains extensible and maintainable without forming any dependency cycles.
> The Acyclic Visitor pattern allows new functions to be added to existing class hierarchies without affecting those
> hierarchies, and without creating the dependency cycles that are inherent to the GangOfFour VisitorPattern.
> The Acyclic Visitor pattern allows new functions to be added to existing class hierarchies without affecting those hierarchies, and without creating the dependency cycles that are inherent to the GangOfFour VisitorPattern.
## Programmatic Example of Acyclic Visitor in Java
In this Java example, we have a hierarchy of modem classes illustrating the Acyclic Visitor pattern. The modems in this hierarchy need to be visited by an external algorithm based on filtering criteria (is it Unix or DOS compatible modem).
Here's the `Modem` hierarchy.
@@ -37,7 +46,9 @@ public abstract class Modem {
}
public class Zoom extends Modem {
...
// Other properties and methods...
@Override
public void accept(ModemVisitor modemVisitor) {
if (modemVisitor instanceof ZoomVisitor) {
@@ -49,7 +60,9 @@ public class Zoom extends Modem {
}
public class Hayes extends Modem {
...
// Other properties and methods...
@Override
public void accept(ModemVisitor modemVisitor) {
if (modemVisitor instanceof HayesVisitor) {
@@ -61,7 +74,7 @@ public class Hayes extends Modem {
## Benefits and Trade-offs of Acyclic Visitor Pattern
The good:
Benefits:
* No dependency cycles between class hierarchies.
* No need to recompile all the visitors if a new one is added.
* Does not cause compilation failure in existing visitors if class hierarchy has a new member.
* Extensible: New operations can be added easily without changing the object structure.
* Decoupled: Reduces coupling between the objects and the operations on them.
* No dependency cycles: Ensures acyclic dependencies, improving maintainability and reducing complexity.
The bad:
Trade-offs:
* Violates [Liskov's Substitution Principle](https://java-design-patterns.com/principles/#liskov-substitution-principle) by showing that it can accept all visitors but actually only being interested in particular visitors.
* Parallel hierarchy of visitors has to be created for all members in visitable class hierarchy.
* Increased complexity: Can introduce additional complexity with the need for multiple visitor interfaces.
* Maintenance overhead: Modifying the object hierarchy requires updating all visitors.
* [Composite](https://java-design-patterns.com/patterns/composite/): Often used in conjunction with Acyclic Visitor to allow treating individual objects and compositions uniformly.
* [Decorator](https://java-design-patterns.com/patterns/decorator/): Can be used alongside to add responsibilities to objects dynamically.
* [Visitor](https://java-design-patterns.com/patterns/visitor/): The Acyclic Visitor pattern is a variation of the Visitor pattern that avoids cyclic dependencies.
## Credits
## References and Credits
* [Acyclic Visitor by Robert C. Martin](http://condor.depaul.edu/dmumaugh/OOT/Design-Principles/acv.pdf)
* [Acyclic Visitor in WikiWikiWeb](https://wiki.c2.com/?AcyclicVisitor)
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI)
* [Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software](https://amzn.to/49NGldq)
* [Java Design Patterns: A Hands-On Experience with Real-World Examples](https://amzn.to/3yhh525)
* [Patterns in Java: A Catalog of Reusable Design Patterns Illustrated with UML](https://amzn.to/4bOtzwF)
* [Acyclic Visitor (Robert C. Martin)](http://condor.depaul.edu/dmumaugh/OOT/Design-Principles/acv.pdf)
title: "Adapter Pattern in Java: Seamless Integration of Incompatible Systems"
shortTitle: Adapter
description: "Learn how the Adapter Design Pattern works in Java with detailed examples and use cases. Understand how it enables compatibility between incompatible interfaces."
category: Structural
language: en
tag:
- Compatibility
- Decoupling
- Gang of Four
- Interface
- Object composition
- Wrapping
---
## Also known as
Wrapper
## Intent
Convert the interface of a class into another interface the clients expect. Adapter lets classes work together that
couldn't otherwise because of incompatible interfaces.
* Wrapper
## Explanation
## Intent of Adapter Design Pattern
The Adapter Design Pattern in Java converts the interface of a class into another interface that clients expect, enabling compatibility.
## Detailed Explanation of Adapter Pattern with Real-World Examples
Real-world example
> Consider that you have some pictures on your memory card and you need to transfer them to your computer. To transfer them, you need some kind of adapter that is compatible with your computer ports so that you can attach a memory card to your computer. In this case card reader is an adapter.
> Another example would be the famous power adapter; a three-legged plug can't be connected to a two-pronged outlet, it needs to use a power adapter that makes it compatible with the two-pronged outlets.
> Yet another example would be a translator translating words spoken by one person to another
> Consider that you have some pictures on your memory card and you need to transfer them to your computer. To transfer them, you need some kind of adapter that is compatible with your computer ports so that you can attach a memory card to your computer. In this case card reader is an adapter. Another example would be the famous power adapter; a three-legged plug can't be connected to a two-pronged outlet, it needs to use a power adapter that makes it compatible with the two-pronged outlets. Yet another example would be a translator translating words spoken by one person to another
In plain words
@@ -29,9 +35,15 @@ Wikipedia says
> In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code.
**Programmatic Example**
Sequence diagram
Consider a captain that can only use rowing boats and cannot sail at all.
## Programmatic Example of Adapter Pattern in Java
The Adapter Pattern example in Java shows how a class with an incompatible interface can be adapted to work with another class.
Consider a wannabe captain that can only use rowing boats but can't sail at all.
First, we have interfaces `RowingBoat` and `FishingBoat`
@@ -48,12 +60,13 @@ public class FishingBoat {
}
```
And captain expects an implementation of `RowingBoat` interface to be able to move
The captain expects an implementation of `RowingBoat` interface to be able to move.
```java
public class Captain {
private final RowingBoat rowingBoat;
// default constructor and setter for rowingBoat
public Captain(RowingBoat rowingBoat) {
this.rowingBoat = rowingBoat;
@@ -65,7 +78,7 @@ public class Captain {
}
```
Now let's say the pirates are coming and our captain needs to escape but there is only a fishing boat available. We need to create an adapter that allows the captain to operate the fishing boat with his rowing boat skills.
Now, let's say the pirates are coming and our captain needs to escape but there is only a fishing boat available. We need to create an adapter that allows the captain to operate the fishing boat with his rowing boat skills.
```java
@Slf4j
@@ -84,56 +97,58 @@ public class FishingBoatAdapter implements RowingBoat {
}
```
And now the `Captain` can use the `FishingBoat` to escape the pirates.
Now the `Captain` can use the `FishingBoat` to escape the pirates.
```java
var captain = new Captain(new FishingBoatAdapter());
captain.row();
public static void main(final String[] args) {
// The captain can only operate rowing boats but with adapter he is able to
// use fishing boats as well
var captain = new Captain(new FishingBoatAdapter());
captain.row();
}
```
## Class diagram

The program outputs:
## Applicability
Use the Adapter pattern when
```
10:25:08.074 [main] INFO com.iluwatar.adapter.FishingBoat -- The fishing boat is sailing
```
## When to Use the Adapter Pattern in Java
Use the Adapter pattern in Java when
* You want to use an existing class, and its interface does not match the one you need
* You want to create a reusable class that cooperates with unrelated or unforeseen classes, that is, classes that don't necessarily have compatible interfaces
* You need to use several existing subclasses, but it's impractical to adapt their interface by subclassing everyone. An object adapter can adapt the interface of its parent class.
* Most of the applications using third-party libraries use adapters as a middle layer between the application and the 3rd party library to decouple the application from the library. If another library has to be used only an adapter for the new library is required without having to change the application code.
Class and object adapters have different trade-offs. A class adapter
Class and object adapters offer different benefits and drawbacks. A class adapter adapts the Adaptee to the Target by binding to a specific Adaptee class, which means it cannot adapt a class and all its subclasses. This type of adapter allows the Adapter to override some of the Adaptee’s behavior because the Adapter is a subclass of the Adaptee. Additionally, it introduces only one object without needing extra pointer indirection to reach the Adaptee.
* Adapts Adaptee to Target by committing to a concrete Adaptee class. As a consequence, a class adapter won’t work when we want to adapt a class and all its subclasses.
* Lets Adapter override some of Adaptee’s behavior since Adapter is a subclass of Adaptee.
* Introduces only one object, and no additional pointer indirection is needed to get to the adaptee.
On the other hand, an object adapter allows a single Adapter to work with multiple Adaptees, including the Adaptee and all its subclasses. This type of adapter can add functionality to all Adaptees simultaneously. However, it makes overriding the Adaptee’s behavior more difficult, as it requires subclassing the Adaptee and having the Adapter refer to this subclass instead of the Adaptee itself.
An object adapter
* Lets a single Adapter work with many Adaptees, that is, the Adaptee itself and all of its subclasses (if any). The Adapter can also add functionality to all Adaptees at once.
* Makes it harder to override Adaptee behavior. It will require subclassing Adaptee and making the Adapter refer to the subclass rather than the Adaptee itself.
## Real-world examples
## Real-World Applications of Adapter Pattern in Java
* `java.io.InputStreamReader` and `java.io.OutputStreamWriter` in the Java IO library.
* GUI component libraries that allow for plug-ins or adapters to convert between different GUI component interfaces.
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)
* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7)
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI)
* [Effective Java](https://amzn.to/4cGk2Jz)
* [Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software](https://amzn.to/49NGldq)
* [J2EE Design Patterns](https://amzn.to/4dpzgmx)
* [Refactoring to Patterns](https://amzn.to/3VOO4F5)
title: "Ambassador Pattern in Java: Simplifying Remote Resource Management"
shortTitle: Ambassador
description: "Explore the Ambassador Pattern in Java, its benefits, use cases, and practical examples. Learn how to decouple and offload common functionalities to improve system performance and maintainability."
category: Integration
language: en
tag:
- API design
- Decoupling
- Cloud distributed
- Fault tolerance
- Proxy
- Resilience
- Scalability
---
## Intent
## Intent of Ambassador Design Pattern
Provide a helper service instance on a client and offload common functionality away from a shared resource.
The Ambassador Pattern in Java helps offload common functionalities such as monitoring, logging, and routing from a shared resource to a helper service instance, enhancing performance and maintainability in distributed systems.
## Explanation
## Detailed Explanation of Ambassador Pattern with Real-World Examples
Realworld example
Real-world example
> A remote service has many clients accessing a function it provides. The service is a legacy application and is
> impossible to update. Large numbers of requests from users are causing connectivity issues. New rules for request
> frequency should be implemented along with latency checks and client-side logging.
> Imagine a busy hotel where guests frequently request restaurant reservations, event tickets, or transportation arrangements. Instead of each guest individually contacting these services, the hotel provides a concierge. The concierge handles these tasks on behalf of the guests, ensuring that reservations are made smoothly, tickets are booked on time, and transportation is scheduled efficiently.
>
> In this analogy, the guests are the client services, the external providers (restaurants, ticket vendors, transportation) are the remote services, and the concierge represents the ambassador service. This setup allows the guests to focus on enjoying their stay while the concierge manages the complexities of external interactions, providing a seamless and enhanced experience.
In plain words
> With the Ambassador pattern, we can implement less-frequent polling from clients along with latency checks and
> logging.
> With the Ambassador pattern, we can implement less-frequent polling from clients along with latency checks and logging.
Microsoft documentation states
> An ambassador service can be thought of as an out-of-process proxy which is co-located with the client. This pattern
> can be useful for offloading common client connectivity tasks such as monitoring, logging, routing,
> security (such as TLS), and resiliency patterns in a language agnostic way. It is often used with legacy applications,
> or other applications that are difficult to modify, in order to extend their networking capabilities. It can also
> enable a specialized team to implement those features.
> An ambassador service can be thought of as an out-of-process proxy which is co-located with the client. This pattern can be useful for offloading common client connectivity tasks such as monitoring, logging, routing, security (such as TLS), and resiliency patterns in a language agnostic way. It is often used with legacy applications, or other applications that are difficult to modify, in order to extend their networking capabilities. It can also enable a specialized team to implement those features.
**Programmatic Example**
Sequence diagram
With the above introduction in mind we will imitate the functionality in this example. We have an interface implemented
by the remote service as well as the ambassador service:
## Programmatic Example of Ambassador Pattern in Java
In this example of the Ambassador Pattern in Java, we demonstrate how to implement latency checks, logging, and retry mechanisms to improve system reliability.
A remote service has many clients accessing a function it provides. The service is a legacy application and is impossible to update. Large numbers of requests from users are causing connectivity issues. New rules for request frequency should be implemented along with latency checks and client-side logging.
With the above introduction in mind we will imitate the functionality in this example. We have an interface implemented by the remote service as well as the ambassador service.
public class RemoteService implements RemoteServiceInterface {
private static RemoteService service = null;
@@ -57,7 +66,8 @@ public class RemoteService implements RemoteServiceInterface {
return service;
}
private RemoteService() {}
private RemoteService() {
}
@Override
public long doRemoteFunction(int value) {
@@ -74,9 +84,10 @@ public class RemoteService implements RemoteServiceInterface {
}
```
A service ambassador adding additional features such as logging, latency checks
A service ambassador adds additional features such as logging and latency checks.
```java
@Slf4j
public class ServiceAmbassador implements RemoteServiceInterface {
private static final int RETRIES = 3;
@@ -125,9 +136,10 @@ public class ServiceAmbassador implements RemoteServiceInterface {
}
```
A client has a local service ambassador used to interact with the remote service:
A client has a local service ambassador used to interact with the remote service.
```java
@Slf4j
public class Client {
private final ServiceAmbassador serviceAmbassador = new ServiceAmbassador();
@@ -156,31 +168,24 @@ public class App {
Here's the output for running the example:
```java
Time taken(ms):111
Service result:120
Time taken(ms):931
Failed to reach remote:(1)
Time taken(ms):665
Failed to reach remote:(2)
Time taken(ms):538
Failed to reach remote:(3)
Service result:-1
Time taken(ms):111
Service result:120
Time taken(ms):931
Failed to reach remote:(1)
Time taken(ms):665
Failed to reach remote:(2)
Time taken(ms):538
Failed to reach remote:(3)
Service result:-1
```
## Class diagram
## When to Use the Ambassador Pattern in Java

* The Ambassador Pattern is particularly beneficial for Cloud Native and Microservices Architectures in Java. It helps in monitoring, logging, and securing inter-service communication, making it ideal for distributed systems.
* Legacy System Integration: Facilitates communication with newer services by handling necessary but non-core functionalities.
* Performance Enhancement: Can be used to cache results or compress data to improve communication efficiency.
## Applicability
Ambassador is applicable when working with a legacy remote service which cannot be modified or would be extremely
difficult to modify. Connectivity features can be implemented on the client avoiding the need for changes on the remote
service.
* Ambassador provides a local interface for a remote service.
* Ambassador provides logging, circuit breaking, retries and security on the client.
## Typical Use Case
Typical use cases include:
* Control access to another object
* Implement logging
@@ -188,15 +193,44 @@ service.
* Offload remote service tasks
* Facilitate network connection
## Known uses
## Benefits and Trade-offs of Ambassador Pattern
Benefits:
* Separation of Concerns: Offloads cross-cutting concerns from the service logic, leading to cleaner, more maintainable code.
* Reusable Infrastructure Logic: The ambassador pattern allows the same logic (e.g., logging, monitoring) to be reused across multiple services.
* Improved Security: Centralizes security features like SSL termination or authentication, reducing the risk of misconfiguration.
* Flexibility: Makes it easier to update or replace infrastructure concerns without modifying the service code.
Trade-offs:
* Increased Complexity: Adds another layer to the architecture, which can complicate the system design and debugging.
* Potential Performance Overhead: The additional network hop can introduce latency and overhead, particularly if not optimized.
* Deployment Overhead: Requires additional resources and management for deploying and scaling ambassador services.
## Real-World Applications of Ambassador Pattern in Java
* Service Mesh Implementations: In a service mesh architecture, like Istio or Linkerd, the Ambassador pattern is often employed as a sidecar proxy that handles inter-service communications. This includes tasks such as service discovery, routing, load balancing, telemetry (metrics and tracing), and security (authentication and authorization).
* API Gateways: API gateways can use the Ambassador pattern to encapsulate common functionalities like rate limiting, caching, request shaping, and authentication. This allows backend services to focus on their core business logic without being burdened by these cross-cutting concerns.
* Logging and Monitoring: An Ambassador can aggregate logs and metrics from various services and forward them to centralized monitoring tools like Prometheus or ELK Stack (Elasticsearch, Logstash, Kibana). This simplifies the logging and monitoring setup for each service and provides a unified view of the system's health.
* Security: Security-related functionalities such as SSL/TLS termination, identity verification, and encryption can be managed by an Ambassador. This ensures consistent security practices across services and reduces the likelihood of security breaches due to misconfigurations.
* Resilience: The Ambassador can implement resilience patterns like circuit breakers, retries, and timeouts. For instance, Netflix's Hystrix library can be used within an Ambassador to prevent cascading failures in a microservices ecosystem.
* Database Proxy: Ambassadors can act as proxies for database connections, providing functionalities like connection pooling, read/write splitting for replicas, and query caching. This offloads significant complexity from the application services.
* Legacy System Integration: In scenarios where modern microservices need to communicate with legacy systems, an Ambassador can serve as an intermediary that translates protocols, handles necessary transformations, and implements modern security practices, easing the integration process.
* Network Optimization: For services deployed across different geographical locations or cloud regions, Ambassadors can optimize communication by compressing data, batching requests, or even implementing smart routing to reduce latency and costs.
* [Kubernetes-native API gateway for microservices](https://github.com/datawire/ambassador)
* [Circuit Breaker](https://java-design-patterns.com/patterns/circuit-breaker/): Often used in conjunction to manage fault tolerance by stopping calls to an unresponsive service.
* [Decorator](https://java-design-patterns.com/patterns/decorator/): The decorator pattern is used to add functionality to an object dynamically, while the ambassador pattern is used to offload functionality to a separate object.
* [Proxy](https://java-design-patterns.com/patterns/proxy/): Shares similarities with the proxy pattern, but the ambassador pattern specifically focuses on offloading ancillary functionalities.
* Sidecar: A similar pattern used in the context of containerized applications, where a sidecar container provides additional functionality to the main application container.
@@ -40,8 +40,7 @@ public class ServiceAmbassador implements RemoteServiceInterface {
privatestaticfinalintRETRIES=3;
privatestaticfinalintDELAY_MS=3000;
ServiceAmbassador(){
}
ServiceAmbassador(){}
@Override
publiclongdoRemoteFunction(intvalue){
Loaded 100 of 3319 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.