### Complete Example Execution Source: https://github.com/iluwatar/java-design-patterns/blob/master/business-delegate/README.md This main method demonstrates the setup and execution of the Business Delegate pattern, showing how the client interacts with the delegate to play different movies. ```java public static void main(String[] args) { // prepare the objects var businessDelegate = new BusinessDelegate(); var businessLookup = new BusinessLookup(); businessLookup.setNetflixService(new NetflixService()); businessLookup.setYouTubeService(new YouTubeService()); businessDelegate.setLookupService(businessLookup); // create the client and use the business delegate var client = new MobileClient(businessDelegate); client.playbackMovie("Die Hard 2"); client.playbackMovie("Maradona: The Greatest Ever"); } ``` -------------------------------- ### Java Server Session Application Setup Source: https://github.com/iluwatar/java-design-patterns/blob/master/server-session/README.md Sets up an HTTP server with contexts for login and logout, and starts a background task for session expiration. Ensure the server port is available. ```java public class App { private static Map sessions = new HashMap<>(); private static Map sessionCreationTimes = new HashMap<>(); private static final long SESSION_EXPIRATION_TIME = 10000; public static void main(String[] args) throws IOException { HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); server.createContext("/login", new LoginHandler(sessions, sessionCreationTimes)); server.createContext("/logout", new LogoutHandler(sessions, sessionCreationTimes)); server.start(); sessionExpirationTask(); } private static void sessionExpirationTask() { new Thread(() -> { while (true) { try { Thread.sleep(SESSION_EXPIRATION_TIME); Instant currentTime = Instant.now(); synchronized (sessions) { synchronized (sessionCreationTimes) { Iterator> iterator = sessionCreationTimes.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = iterator.next(); if (entry.getValue().plusMillis(SESSION_EXPIRATION_TIME).isBefore(currentTime)) { sessions.remove(entry.getKey()); iterator.remove(); } } } } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }).start(); } } ``` -------------------------------- ### Java Reactor Pattern Application Setup Source: https://github.com/iluwatar/java-design-patterns/blob/master/reactor/README.md This Java code demonstrates the setup of an application using the Reactor pattern. It initializes a dispatcher, reactor, handler, and registers channels before starting the reactor to handle events. ```java } } ``` ``` -------------------------------- ### Console Output Example Source: https://github.com/iluwatar/java-design-patterns/blob/master/queue-based-load-leveling/README.md Illustrates the typical console output when running the Queue-Based Load Leveling pattern example, showing task submission and service. ```text [main] INFO App - Submitting TaskGenerators and ServiceExecutor threads. [main] INFO App - Initiating shutdown. Executor will shutdown only after all the Threads are completed. [pool-1-thread-2] INFO TaskGenerator - Message-1 submitted by pool-1-thread-2 [pool-1-thread-1] INFO TaskGenerator - Message-5 submitted by pool-1-thread-1 [pool-1-thread-1] INFO TaskGenerator - Message-4 submitted by pool-1-thread-1 [pool-1-thread-2] INFO TaskGenerator - Message-2 submitted by pool-1-thread-2 [pool-1-thread-1] INFO TaskGenerator - Message-3 submitted by pool-1-thread-1 [pool-1-thread-2] INFO TaskGenerator - Message-1 submitted by pool-1-thread-2 [pool-1-thread-1] INFO TaskGenerator - Message-2 submitted by pool-1-thread-1 [pool-1-thread-2] INFO ServiceExecutor - Message-1 submitted by pool-1-thread-2 is served. [pool-1-thread-1] INFO TaskGenerator - Message-1 submitted by pool-1-thread-1 [pool-1-thread-2] INFO ServiceExecutor - Message-5 submitted by pool-1-thread-1 is served. [pool-1-thread-2] INFO ServiceExecutor - Message-4 submitted by pool-1-thread-1 is served. [pool-1-thread-2] INFO ServiceExecutor - Message-2 submitted by pool-1-thread-2 is served. [pool-1-thread-2] INFO ServiceExecutor - Message-3 submitted by pool-1-thread-1 is served. [pool-1-thread-2] INFO ServiceExecutor - Message-1 submitted by pool-1-thread-2 is served. [pool-1-thread-2] INFO ServiceExecutor - Message-2 submitted by pool-1-thread-1 is served. [pool-1-thread-2] INFO ServiceExecutor - Message-1 submitted by pool-1-thread-1 is served. [pool-1-thread-2] INFO ServiceExecutor - Service Executor: Waiting for Messages to serve .. ``` -------------------------------- ### Example Actor System Usage in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/actor-model/README.md Demonstrates starting two actors, sending messages between them, and then gracefully stopping them and the system. Includes a delay to allow message processing. ```java public class App { public static void main(String[] args) { ActorSystem system = new ActorSystem(); Actor srijan = new ExampleActor(system); Actor ansh = new ExampleActor2(system); system.startActor(srijan); system.startActor(ansh); ansh.send(new Message("Hello ansh", srijan.getActorId())); srijan.send(new Message("Hello srijan!", ansh.getActorId())); Thread.sleep(1000); // Give time for messages to process srijan.stop(); // Stop the actor gracefully ansh.stop(); system.shutdown(); // Stop the actor system } } ``` -------------------------------- ### Example Character Creation Source: https://github.com/iluwatar/java-design-patterns/blob/master/step-builder/README.md Demonstrates the guided, step-by-step construction of different character types (warrior, mage, thief) using the Step Builder pattern. ```java public static void main(String[] args) { var warrior = CharacterStepBuilder .newBuilder() .name("Amberjill") .fighterClass("Paladin") .withWeapon("Sword") .noAbilities() .build(); LOGGER.info(warrior.toString()); var mage = CharacterStepBuilder .newBuilder() .name("Riobard") .wizardClass("Sorcerer") .withSpell("Fireball") .withAbility("Fire Aura") .withAbility("Teleport") .noMoreAbilities() .build(); LOGGER.info(mage.toString()); var thief = CharacterStepBuilder .newBuilder() .name("Desmond") .fighterClass("Rogue") .noWeapon() .build(); LOGGER.info(thief.toString()); } ``` -------------------------------- ### Console Output Example Source: https://github.com/iluwatar/java-design-patterns/blob/master/business-delegate/README.md The expected console output when the complete example is executed, showing which services processed the movie requests. ```text 21:15:33.790 [main] INFO com.iluwatar.business.delegate.NetflixService - NetflixService is now processing 21:15:33.794 [main] INFO com.iluwatar.business.delegate.YouTubeService - YouTubeService is now processing ``` -------------------------------- ### Service Locator Pattern Example Output in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/service-locator/README.md Shows the expected log output when running the Service Locator pattern example. It illustrates service lookup, creation, execution, and caching. ```text 15:39:51.417 [main] INFO com.iluwatar.servicelocator.InitContext -- Looking up service A and creating new service for A 15:39:51.419 [main] INFO com.iluwatar.servicelocator.ServiceImpl -- Service jndi/serviceA is now executing with id 56 15:39:51.420 [main] INFO com.iluwatar.servicelocator.InitContext -- Looking up service B and creating new service for B 15:39:51.420 [main] INFO com.iluwatar.servicelocator.ServiceImpl -- Service jndi/serviceB is now executing with id 196 15:39:51.420 [main] INFO com.iluwatar.servicelocator.ServiceCache -- (cache call) Fetched service jndi/serviceA(56) from cache... ! 15:39:51.420 [main] INFO com.iluwatar.servicelocator.ServiceImpl -- Service jndi/serviceA is now executing with id 56 15:39:51.420 [main] INFO com.iluwatar.servicelocator.ServiceCache -- (cache call) Fetched service jndi/serviceA(56) from cache... ! 15:39:51.420 [main] INFO com.iluwatar.servicelocator.ServiceImpl -- Service jndi/serviceA is now executing with id 56 ``` -------------------------------- ### Example Frontend Components in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/microservices-client-side-ui-composition/README.md Provides example implementations of the FrontendComponent interface for 'Product' and 'Cart' modules. These components define how to fetch data specific to their domain. ```java public class ProductComponent implements FrontendComponent { @Override public String fetchData(Map params) { return "Displaying Products: " + params.getOrDefault("category", "all"); } } public class CartComponent implements FrontendComponent { @Override public String fetchData(Map params) { return "Displaying Cart for User: " + params.getOrDefault("userId", "unknown"); } } ``` -------------------------------- ### Example Output of Clean Architecture Simulation Source: https://github.com/iluwatar/java-design-patterns/blob/master/clean-architecture/README.md This markdown block shows the expected output from the Java programmatic example, detailing the calculated total and the confirmation of a placed order. ```markdown Total: $2000.0 Order placed! Order ID: ORDER-1743349969254, Total: $2000.0 ``` -------------------------------- ### Program Output Example Source: https://github.com/iluwatar/java-design-patterns/blob/master/producer-consumer/README.md Illustrates the typical log output from the consumer threads as they process items from the queue. ```text 08:10:08.008 [pool-1-thread-3] INFO com.iluwatar.producer.consumer.Consumer -- Consumer [Consumer_0] consume item [0] produced by [Producer_1] 08:10:08.008 [pool-1-thread-4] INFO com.iluwatar.producer.consumer.Consumer -- Consumer [Consumer_1] consume item [0] produced by [Producer_0] 08:10:08.517 [pool-1-thread-5] INFO com.iluwatar.producer.consumer.Consumer -- Consumer [Consumer_2] consume item [1] produced by [Producer_0] 08:10:08.952 [pool-1-thread-3] INFO com.iluwatar.producer.consumer.Consumer -- Consumer [Consumer_0] consume item [1] produced by [Producer_1] 08:10:09.208 [pool-1-thread-4] INFO com.iluwatar.producer.consumer.Consumer -- Consumer [Consumer_1] consume item [2] produced by [Producer_0] 08:10:09.354 [pool-1-thread-5] INFO com.iluwatar.producer.consumer.Consumer -- Consumer [Consumer_2] consume item [2] produced by [Producer_1] 08:10:10.214 [pool-1-thread-3] INFO com.iluwatar.producer.consumer.Consumer -- Consumer [Consumer_0] consume item [3] produced by [Producer_1] 08:10:10.585 [pool-1-thread-4] INFO com.iluwatar.producer.consumer.Consumer -- Consumer [Consumer_1] consume item [3] produced by [Producer_0] 08:10:11.530 [pool-1-thread-5] INFO com.iluwatar.producer.consumer.Consumer -- Consumer [Consumer_2] consume item [4] produced by [Producer_1] 08:10:11.682 [pool-1-thread-3] INFO com.iluwatar.producer.consumer.Consumer -- Consumer [Consumer_0] consume item [4] produced by [Producer_0] 08:10:11.781 [pool-1-thread-4] INFO com.iluwatar.producer.consumer.Consumer -- Consumer [Consumer_1] consume item [5] produced by [Producer_0] 08:10:12.209 [pool-1-thread-5] INFO com.iluwatar.producer.consumer.Consumer -- Consumer [Consumer_2] consume item [5] produced by [Producer_1] 08:10:13.045 [pool-1-thread-3] INFO com.iluwatar.producer.consumer.Consumer -- Consumer [Consumer_0] consume item [6] produced by [Producer_0] ``` -------------------------------- ### Application Entry Point: App Class Source: https://github.com/iluwatar/java-design-patterns/blob/master/model-view-presenter/README.md Wires together the Model, View, and Presenter components to initialize and start the application. ```java public class App { public static void main(String[] args) { var loader = new FileLoader(); var frame = new FileSelectorJFrame(); var presenter = new FileSelectorPresenter(frame); presenter.setLoader(loader); presenter.start(); } } ``` -------------------------------- ### Application Setup with Jersey Source: https://github.com/iluwatar/java-design-patterns/blob/master/partial-response/README.md Initializes the web server using Jersey and registers the VideoResource. The server listens on http://localhost:8080/. ```java public class App { public static void main(String[] args) { ResourceConfig config = new ResourceConfig(); config.register(VideoResource.class); SimpleContainerFactory.create("http://localhost:8080/", config); } } ``` -------------------------------- ### Main Application Setup and Execution Source: https://github.com/iluwatar/java-design-patterns/blob/master/unit-of-work/README.md Sets up the Weapon entities, initializes the ArmsDealer repository, performs operations, and commits them. This demonstrates the practical usage of the Unit of Work pattern. ```java import java.util.HashMap; public class Main { public static void main(String[] args) { // create some weapons var enchantedHammer = new Weapon(1, "enchanted hammer"); var brokenGreatSword = new Weapon(2, "broken great sword"); var silverTrident = new Weapon(3, "silver trident"); // create repository var weaponRepository = new ArmsDealer(new HashMap<>(), new WeaponDatabase()); // perform operations on the weapons weaponRepository.registerNew(enchantedHammer); weaponRepository.registerModified(silverTrident); weaponRepository.registerDeleted(brokenGreatSword); weaponRepository.commit(); } } ``` -------------------------------- ### Demonstrate Dependency Injection Usage in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/dependency-injection/README.md Shows how to instantiate and use `SimpleWizard`, `AdvancedWizard`, `AdvancedSorceress`, and a `GuiceWizard` with different tobacco dependencies. Includes setup for Guice DI. ```java public static void main(String[] args) { var simpleWizard = new SimpleWizard(); simpleWizard.smoke(); var advancedWizard = new AdvancedWizard(new SecondBreakfastTobacco()); advancedWizard.smoke(); var advancedSorceress = new AdvancedSorceress(); advancedSorceress.setTobacco(new SecondBreakfastTobacco()); advancedSorceress.smoke(); var injector = Guice.createInjector(new TobaccoModule()); var guiceWizard = injector.getInstance(GuiceWizard.class); guiceWizard.smoke(); } ``` -------------------------------- ### Reactor Pattern Output Log Source: https://github.com/iluwatar/java-design-patterns/blob/master/reactor/README.md This is the expected output log when running the Reactor Pattern example. It shows the binding of TCP and UDP sockets and the reactor starting to wait for events. ```log 09:50:08.317 [main] INFO com.iluwatar.reactor.framework.NioServerSocketChannel -- Bound TCP socket at port: 16666 09:50:08.320 [main] INFO com.iluwatar.reactor.framework.NioServerSocketChannel -- Bound TCP socket at port: 16667 09:50:08.323 [main] INFO com.iluwatar.reactor.framework.NioDatagramChannel -- Bound UDP socket at port: 16668 09:50:08.324 [main] INFO com.iluwatar.reactor.framework.NioDatagramChannel -- Bound UDP socket at port: 16669 09:50:08.324 [pool-2-thread-1] INFO com.iluwatar.reactor.framework.NioReactor -- Reactor started, waiting for events... ``` -------------------------------- ### Main Example Execution Source: https://github.com/iluwatar/java-design-patterns/blob/master/command/README.md Demonstrates the Command pattern by having a Wizard cast spells on a Goblin, then undoing and redoing them. This showcases the full lifecycle of command execution and state changes. ```java public static void main(String[] args) { var wizard = new Wizard(); var goblin = new Goblin(); goblin.printStatus(); wizard.castSpell(goblin::changeSize); goblin.printStatus(); wizard.castSpell(goblin::changeVisibility); goblin.printStatus(); wizard.undoLastSpell(); goblin.printStatus(); wizard.undoLastSpell(); goblin.printStatus(); wizard.redoLastSpell(); goblin.printStatus(); wizard.redoLastSpell(); goblin.printStatus(); } ``` -------------------------------- ### Demonstrate Data Bus Pattern in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/data-bus/README.md Sets up the Data Bus, subscribes different member types, and publishes a StartingData event to show selective message handling. ```java class App { public static void main(String[] args) { final var bus = DataBus.getInstance(); bus.subscribe(new StatusMember(1)); bus.subscribe(new StatusMember(2)); final var foo = new MessageCollectorMember("Foo"); final var bar = new MessageCollectorMember("Bar"); bus.subscribe(foo); bus.publish(StartingData.of(LocalDateTime.now())); } } ``` -------------------------------- ### Console Output of RAII Example (Java) Source: https://github.com/iluwatar/java-design-patterns/blob/master/resource-acquisition-is-initialization/README.md The expected console output when running the RAII example with SlidingDoor and TreasureChest. ```text 10:07:14.833 [main] INFO com.iluwatar.resource.acquisition.is.initialization.SlidingDoor -- Sliding door opens. 10:07:14.835 [main] INFO com.iluwatar.resource.acquisition.is.initialization.App -- Walking in. 10:07:14.835 [main] INFO com.iluwatar.resource.acquisition.is.initialization.SlidingDoor -- Sliding door closes. 10:07:14.835 [main] INFO com.iluwatar.resource.acquisition.is.initialization.TreasureChest -- Treasure chest opens. 10:07:14.835 [main] INFO com.iluwatar.resource.acquisition.is.initialization.App -- Looting contents. 10:07:14.835 [main] INFO com.iluwatar.resource.acquisition.is.initialization.TreasureChest -- Treasure chest closes. ``` -------------------------------- ### Main Method for Virtual Machine Execution Source: https://github.com/iluwatar/java-design-patterns/blob/master/bytecode/README.md This is the main entry point for the program, demonstrating how to initialize and use the VirtualMachine. It executes a sequence of instructions converted to bytecode, simulating a series of operations on wizard attributes. ```java public static void main(String[] args) { var vm = new VirtualMachine( new Wizard(45, 7, 11, 0, 0), new Wizard(36, 18, 8, 0, 0)); vm.execute(InstructionConverterUtil.convertToByteCode(LITERAL_0)); vm.execute(InstructionConverterUtil.convertToByteCode(LITERAL_0)); vm.execute(InstructionConverterUtil.convertToByteCode(String.format(HEALTH_PATTERN, "GET"))); vm.execute(InstructionConverterUtil.convertToByteCode(LITERAL_0)); vm.execute(InstructionConverterUtil.convertToByteCode(GET_AGILITY)); vm.execute(InstructionConverterUtil.convertToByteCode(LITERAL_0)); vm.execute(InstructionConverterUtil.convertToByteCode(GET_WISDOM)); vm.execute(InstructionConverterUtil.convertToByteCode(ADD)); vm.execute(InstructionConverterUtil.convertToByteCode(LITERAL_2)); vm.execute(InstructionConverterUtil.convertToByteCode(DIVIDE)); vm.execute(InstructionConverterUtil.convertToByteCode(ADD)); vm.execute(InstructionConverterUtil.convertToByteCode(String.format(HEALTH_PATTERN, "SET"))); } ``` -------------------------------- ### Demonstrate Role Object Pattern Usage Source: https://github.com/iluwatar/java-design-patterns/blob/master/role-object/README.md Example of creating a customer with multiple roles, checking for roles, and invoking role-specific methods. ```java public static void main(String[] args) { var customer = Customer.newCustomer(BORROWER, INVESTOR); LOGGER.info("New customer created : {}", customer); var hasBorrowerRole = customer.hasRole(BORROWER); LOGGER.info("Customer has a borrower role - {}", hasBorrowerRole); var hasInvestorRole = customer.hasRole(INVESTOR); LOGGER.info("Customer has an investor role - {}", hasInvestorRole); customer.getRole(INVESTOR, InvestorRole.class) .ifPresent(inv -> { inv.setAmountToInvest(1000); inv.setName("Billy"); }); customer.getRole(BORROWER, BorrowerRole.class) .ifPresent(inv -> inv.setName("Johny")); customer.getRole(INVESTOR, InvestorRole.class) .map(InvestorRole::invest) .ifPresent(LOGGER::info); customer.getRole(BORROWER, BorrowerRole.class) .map(BorrowerRole::borrow) .ifPresent(LOGGER::info); } ``` -------------------------------- ### Example Output Source: https://github.com/iluwatar/java-design-patterns/blob/master/ambassador/README.md Illustrates the expected output when running the Ambassador Pattern example, showing latency, retries, and final results. ```text 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 ``` -------------------------------- ### Start Asynchronous Event in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/event-based-asynchronous/README.md Illustrates how an `AsyncEvent` is started in a separate thread. This prevents the main thread from being blocked during event execution. ```java @Override public void start() { Thread thread = new Thread(() -> { try { handleRunStart(); Thread.sleep(getRuntime().toMillis()); handleRunComplete(); } catch (InterruptedException e) { handleRunFailure(e.getMessage()); } }); thread.start(); } ``` -------------------------------- ### App Class: Entry Point for MVI Example Source: https://github.com/iluwatar/java-design-patterns/blob/master/model-view-intent/README.md Serves as the application's entry point, initializing the View and ViewModel, and simulating user interactions with the calculator. ```java public final class App { private static final double RANDOM_VARIABLE = 10.0; public static void main(final String[] args) { var view = new CalculatorView(new CalculatorViewModel()); var variable1 = RANDOM_VARIABLE; view.setVariable(variable1); view.add(); view.displayTotal(); variable1 = 2.0; view.setVariable(variable1); view.subtract(); view.divide(); view.multiply(); view.displayTotal(); } private App() { } } ``` -------------------------------- ### Console Output of Strangler Pattern Example Source: https://github.com/iluwatar/java-design-patterns/blob/master/strangler/README.md Shows the log output generated during the execution of the Strangler pattern example, illustrating the behavior of each system stage. ```log 13:02:25.030 [main] INFO com.iluwatar.strangler.OldArithmetic -- Arithmetic sum 1.0 13:02:25.032 [main] INFO com.iluwatar.strangler.OldSource -- Source module 1.0 13:02:25.032 [main] INFO com.iluwatar.strangler.OldArithmetic -- Arithmetic mul 1.0 13:02:25.032 [main] INFO com.iluwatar.strangler.OldSource -- Source module 1.0 13:02:25.032 [main] INFO com.iluwatar.strangler.HalfArithmetic -- Arithmetic sum 1.5 13:02:25.032 [main] INFO com.iluwatar.strangler.HalfSource -- Source module 1.5 13:02:25.033 [main] INFO com.iluwatar.strangler.HalfArithmetic -- Arithmetic mul 1.5 13:02:25.033 [main] INFO com.iluwatar.strangler.OldSource -- Source module 1.0 13:02:25.033 [main] INFO com.iluwatar.strangler.HalfArithmetic -- Arithmetic check zero 1.5 13:02:25.033 [main] INFO com.iluwatar.strangler.HalfSource -- Source module 1.5 13:02:25.034 [main] INFO com.iluwatar.strangler.NewArithmetic -- Arithmetic sum 2.0 13:02:25.034 [main] INFO com.iluwatar.strangler.NewSource -- Source module 2.0 13:02:25.034 [main] INFO com.iluwatar.strangler.NewArithmetic -- Arithmetic mul 2.0 13:02:25.034 [main] INFO com.iluwatar.strangler.NewSource -- Source module 2.0 13:02:25.034 [main] INFO com.iluwatar.strangler.NewArithmetic -- Arithmetic check zero 2.0 13:02:25.035 [main] INFO com.iluwatar.strangler.NewSource -- Source module 2.0 ``` -------------------------------- ### Main Execution - Example Usage of MapReduce Source: https://github.com/iluwatar/java-design-patterns/blob/master/map-reduce/README.md Demonstrates how to run the MapReduce process with sample inputs and prints the resulting aggregated key-value pairs. Ensure Mapper, Shuffler, and Reducer classes are implemented and accessible. ```java public static void main(String[] args) { List inputs = Arrays.asList( "Hello world hello", "MapReduce is fun", "Hello from the other side", "Hello world" ); List> result = MapReduce.mapReduce(inputs); for (Map.Entry entry : result) { System.out.println(entry.getKey() + ": " + entry.getValue()); } } ``` -------------------------------- ### Example Usage: Full Publish-Subscribe Flow Source: https://github.com/iluwatar/java-design-patterns/blob/master/publish-subscribe/README.md Demonstrates the complete workflow of the Publish-Subscribe pattern. This includes creating a publisher, registering topics, creating and subscribing subscribers, publishing messages, and dynamically managing subscriptions. ```java public static void main(String[] args) throws InterruptedException { final String topicWeather = "WEATHER"; final String topicTemperature = "TEMPERATURE"; final String topicCustomerSupport = "CUSTOMER_SUPPORT"; // 1. create the publisher. Publisher publisher = new PublisherImpl(); // 2. define the topics and register on publisher Topic weatherTopic = new Topic(topicWeather); publisher.registerTopic(weatherTopic); Topic temperatureTopic = new Topic(topicTemperature); publisher.registerTopic(temperatureTopic); Topic supportTopic = new Topic(topicCustomerSupport); publisher.registerTopic(supportTopic); // 3. Create the subscribers and subscribe to the relevant topics // weatherSub1 will subscribe to two topics WEATHER and TEMPERATURE. Subscriber weatherSub1 = new WeatherSubscriber(); weatherTopic.addSubscriber(weatherSub1); temperatureTopic.addSubscriber(weatherSub1); // weatherSub2 will subscribe to WEATHER topic Subscriber weatherSub2 = new WeatherSubscriber(); weatherTopic.addSubscriber(weatherSub2); // delayedWeatherSub will subscribe to WEATHER topic // NOTE :: DelayedWeatherSubscriber has a 0.2 sec delay of processing message. Subscriber delayedWeatherSub = new DelayedWeatherSubscriber(); weatherTopic.addSubscriber(delayedWeatherSub); // subscribe the customer support subscribers to the CUSTOMER_SUPPORT topic. Subscriber supportSub1 = new CustomerSupportSubscriber(); supportTopic.addSubscriber(supportSub1); Subscriber supportSub2 = new CustomerSupportSubscriber(); supportTopic.addSubscriber(supportSub2); // 4. publish message from each topic publisher.publish(weatherTopic, new Message("earthquake")); publisher.publish(temperatureTopic, new Message("23C")); publisher.publish(supportTopic, new Message("support@test.de")); // 5. unregister subscriber from TEMPERATURE topic temperatureTopic.removeSubscriber(weatherSub1); // 6. publish message under TEMPERATURE topic publisher.publish(temperatureTopic, new Message("0C")); /* * Finally, we wait for the subscribers to consume messages to check the output. * The output can change on each run, depending on how long the execution on each * subscriber would take * Expected behavior: * - weatherSub1 will consume earthquake and 23C * - weatherSub2 will consume earthquake * - delayedWeatherSub will take longer and consume earthquake * - supportSub1, supportSub2 will consume support@test.de * - the message 0C will not be consumed because weatherSub1 unsubscribed from TEMPERATURE topic */ TimeUnit.SECONDS.sleep(2); } ``` -------------------------------- ### Main Application Entry Point Source: https://github.com/iluwatar/java-design-patterns/blob/master/ambassador/README.md Sets up multiple clients and invokes their services to demonstrate the Ambassador Pattern in action. ```java public class App { public static void main(String[] args) { var host1 = new Client(); var host2 = new Client(); host1.useService(12); host2.useService(73); } } ``` -------------------------------- ### Program Output of Dependency Injection Example in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/dependency-injection/README.md The expected output logs from running the dependency injection example, showing which wizard smoked which tobacco. ```text 11:54:05.205 [main] INFO com.iluwatar.dependency.injection.Tobacco -- SimpleWizard smoking OldTobyTobacco 11:54:05.207 [main] INFO com.iluwatar.dependency.injection.Tobacco -- AdvancedWizard smoking SecondBreakfastTobacco 11:54:05.207 [main] INFO com.iluwatar.dependency.injection.Tobacco -- AdvancedSorceress smoking SecondBreakfastTobacco 11:54:05.308 [main] INFO com.iluwatar.dependency.injection.Tobacco -- GuiceWizard smoking RivendellTobacco ``` -------------------------------- ### Start Synchronous Event in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/event-based-asynchronous/README.md Illustrates how a `SyncEvent` is started on the main thread. This blocks the main thread until the event completes, unlike asynchronous events. ```java @Override public void start() { try { handleRunStart(); Thread.sleep(getRuntime().toMillis()); handleRunComplete(); } catch (InterruptedException e) { handleRunFailure(e.getMessage()); } } ``` -------------------------------- ### Pipeline Execution Example Source: https://github.com/iluwatar/java-design-patterns/blob/master/pipeline/README.md Demonstrates how to create and execute a pipeline with multiple handlers. The input string is processed sequentially through each added handler. ```java public static void main(String[] args) { LOGGER.info("Creating pipeline"); var filters = new Pipeline<>(new RemoveAlphabetsHandler()) .addHandler(new RemoveDigitsHandler()) .addHandler(new ConvertToCharArrayHandler()); var input = "GoYankees123!"; LOGGER.info("Executing pipeline with input: {}", input); var output = filters.execute(input); LOGGER.info("Pipeline output: {}", output); } ``` -------------------------------- ### Programmatic Example of Strategy Pattern in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/strategy/README.md This example demonstrates the execution of different strategies for fighting dragons. It shows the output logs when different strategies are applied. ```java 13:06:36.637 [main] INFO com.iluwatar.strategy.App -- Red dragon emerges. 13:06:36.637 [main] INFO com.iluwatar.strategy.LambdaStrategy -- You shoot the dragon with the magical crossbow and it falls dead on the ground! 13:06:36.637 [main] INFO com.iluwatar.strategy.App -- Black dragon lands before you. 13:06:36.637 [main] INFO com.iluwatar.strategy.LambdaStrategy -- You cast the spell of disintegration and the dragon vaporizes in a pile of dust! ``` -------------------------------- ### Execute Task with Callback in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/callback/README.md Demonstrates how to instantiate a task and execute it, providing a callback function that is invoked upon task completion. ```java public static void main(final String[] args) { var task = new SimpleTask(); task.executeWith(() -> LOGGER.info("I'm done now.")); } ``` -------------------------------- ### Main Application Class for Fan-Out/Fan-In Example in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/fanout-fanin/README.md Drives the Fan-Out/Fan-In pattern example. It initializes numbers, creates SquareNumberRequests, and calls the fanOutFanIn method to process them. ```java public static void main(String[] args) { final List numbers = Arrays.asList(1L, 3L, 4L, 7L, 8L); LOGGER.info("Numbers to be squared and get sum --> {}", numbers); final List requests = numbers.stream().map(SquareNumberRequest::new).toList(); var consumer = new Consumer(0L); // Pass the request and the consumer to fanOutFanIn or sometimes referred as Orchestrator // function final Long sumOfSquaredNumbers = FanOutFanIn.fanOutFanIn(requests, consumer); LOGGER.info("Sum of all squared numbers --> {}", sumOfSquaredNumbers); } ``` -------------------------------- ### Application Entry Point with Update Method Pattern in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/update-method/README.md Sets up the game world, adds entities, starts the game loop, and stops it after a specified duration. ```java @Slf4j public class App { private static final int GAME_RUNNING_TIME = 2000; public static void main(String[] args) { try { var world = new World(); var skeleton1 = new Skeleton(1, 10); var skeleton2 = new Skeleton(2, 70); var statue = new Statue(3, 20); world.addEntity(skeleton1); world.addEntity(skeleton2); world.addEntity(statue); world.run(); Thread.sleep(GAME_RUNNING_TIME); world.stop(); } catch (InterruptedException e) { LOGGER.error(e.getMessage()); } } } ``` -------------------------------- ### Main Application for Throttling Example Source: https://github.com/iluwatar/java-design-patterns/blob/master/throttling/README.md Sets up the throttling scenario with different customer limits and simulates service calls using an `ExecutorService`. It demonstrates how the `Bartender` enforces call rates. ```java import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; import lombok.extern.slf4j.Slf4j; @Slf4j public class App { public static void main(String[] args) { var callsCount = new CallsCount(); var human = new BarCustomer("young human", 2, callsCount); var dwarf = new BarCustomer("dwarf soldier", 4, callsCount); var executorService = Executors.newFixedThreadPool(2); executorService.execute(() -> makeServiceCalls(human, callsCount)); executorService.execute(() -> makeServiceCalls(dwarf, callsCount)); executorService.shutdown(); try { if (!executorService.awaitTermination(10, TimeUnit.SECONDS)) { executorService.shutdownNow(); } } catch (InterruptedException e) { executorService.shutdownNow(); } } private static void makeServiceCalls(BarCustomer barCustomer, CallsCount callsCount) { var timer = new ThrottleTimerImpl(1000, callsCount); var service = new Bartender(timer, callsCount); // Sleep is introduced to keep the output in check and easy to view and analyze the results. IntStream.range(0, 50).forEach(i -> { service.orderDrink(barCustomer); try { Thread.sleep(100); } catch (InterruptedException e) { LOGGER.error("Thread interrupted: {}", e.getMessage()); } }); } } ``` -------------------------------- ### Signup Controller for Signup Page Source: https://github.com/iluwatar/java-design-patterns/blob/master/page-controller/README.md Handles GET and POST requests for the /signup path. GET displays the signup page, and POST processes the form and redirects. ```java import org.springframework.stereotype.Controller; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.servlet.mvc.support.RedirectAttributes; @Controller @Component public class SignupController { SignupView view = new SignupView(); @GetMapping("/signup") public String getSignup() { return view.display(); } @PostMapping("/signup") public String create(SignupModel form, RedirectAttributes redirectAttributes) { redirectAttributes.addAttribute("name", form.getName()); redirectAttributes.addAttribute("email", form.getEmail()); redirectAttributes.addFlashAttribute("userInfo", form); return view.redirect(form); } } ``` -------------------------------- ### Main Application Entry Point Source: https://github.com/iluwatar/java-design-patterns/blob/master/data-locality/README.md The main method creates a GameEntity, initializes its components, and runs the update loop, demonstrating the pattern's application. ```java public class Application { public static void main(String[] args) { var gameEntity = new GameEntity(NUM_ENTITIES); gameEntity.start(); gameEntity.update(); } } ``` -------------------------------- ### Create, Start, and Manage Synchronous Event in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/event-based-asynchronous/README.md Demonstrates the lifecycle of a synchronous event using the `EventManager`. This includes creating, starting, checking status, and canceling the event. ```java EventManager eventManager = new EventManager(); int syncEventId = eventManager.create(Duration.ofSeconds(60)); eventManager.start(syncEventId); eventManager.status(syncEventId); eventManager.cancel(syncEventId); ``` -------------------------------- ### Client Session Pattern Application Example Source: https://github.com/iluwatar/java-design-patterns/blob/master/client-session/README.md Demonstrates the usage of the Server and Session classes by creating sessions, requests, and processing them on the server. ```java public class App { public static void main(String[] args) { var server = new Server("localhost", 8080); var session1 = server.getSession("Session1"); var session2 = server.getSession("Session2"); var request1 = new Request("Data1", session1); var request2 = new Request("Data2", session2); server.process(request1); server.process(request2); } } ``` -------------------------------- ### Create, Start, and Manage Asynchronous Event in Java Source: https://github.com/iluwatar/java-design-patterns/blob/master/event-based-asynchronous/README.md Demonstrates the lifecycle of an asynchronous event using the `EventManager`. This includes creating, starting, checking status, and canceling the event. ```java EventManager eventManager = new EventManager(); int asyncEventId = eventManager.createAsync(Duration.ofSeconds(60)); eventManager.start(asyncEventId); eventManager.status(asyncEventId); eventManager.cancel(asyncEventId); ``` -------------------------------- ### Build Microservices with Maven Source: https://github.com/iluwatar/java-design-patterns/blob/master/microservices-self-registration/README.md Navigate to the root directory of each microservice project and execute the Maven clean install command to build them individually. ```bash cd eurekaserver mvn clean install cd ../greetingservice mvn clean install cd ../contextservice mvn clean install ``` -------------------------------- ### Spring Boot Application for Single Table Inheritance Example Source: https://github.com/iluwatar/java-design-patterns/blob/master/single-table-inheritance/README.md The main application class that sets up and runs the Single Table Inheritance example using Spring Boot and CommandLineRunner. ```java @SpringBootApplication @AllArgsConstructor public class SingleTableInheritance implements CommandLineRunner { //Autowiring the VehicleService class to execute the business logic methods private final VehicleService vehicleService; public static void main(String[] args) { SpringApplication.run(SingleTableInheritance.class, args); } @Override public void run(String... args) { Logger log = LoggerFactory.getLogger(SingleTableInheritance.class); log.info("Saving Vehicles :- "); // Saving Car to DB as a Vehicle Vehicle vehicle1 = new Car("Tesla", "Model S", 4, 825); Vehicle car1 = vehicleService.saveVehicle(vehicle1); log.info("Vehicle 1 saved : {}", car1); // Saving Truck to DB as a Vehicle Vehicle vehicle2 = new Truck("Ford", "F-150", 3325, 14000); Vehicle truck1 = vehicleService.saveVehicle(vehicle2); log.info("Vehicle 2 saved : {}\n", truck1); log.info("Fetching Vehicles :- "); // Fetching the Car from DB Car savedCar1 = (Car) vehicleService.getVehicle(vehicle1.getVehicleId()); log.info("Fetching Car1 from DB : {}", savedCar1); // Fetching the Truck from DB Truck savedTruck1 = (Truck) vehicleService.getVehicle(vehicle2.getVehicleId()); log.info("Fetching Truck1 from DB : {}\n", savedTruck1); log.info("Fetching All Vehicles :- "); // Fetching the Vehicles present in the DB List allVehiclesFromDb = vehicleService.getAllVehicles(); allVehiclesFromDb.forEach(s -> log.info(s.toString())); } } ``` -------------------------------- ### Demonstrate Visitor Pattern Usage Source: https://github.com/iluwatar/java-design-patterns/blob/master/visitor/README.md This main method sets up an army hierarchy and applies different visitors to showcase their functionality. ```java public static void main(String[] args) { var commander = new Commander( new Sergeant(new Soldier(), new Soldier(), new Soldier()), new Sergeant(new Soldier(), new Soldier(), new Soldier()) ); commander.accept(new SoldierVisitor()); commander.accept(new SergeantVisitor()); commander.accept(new CommanderVisitor()); } ``` -------------------------------- ### Dynamic Proxy Example Output Source: https://github.com/iluwatar/java-design-patterns/blob/master/dynamic-proxy/README.md This output shows the console logs generated by the dynamic proxy example. It highlights the intercepted method calls and the data retrieved from the proxied service. ```log 16:05:41.964 [main] INFO com.iluwatar.dynamicproxy.AlbumInvocationHandler -- ===== Calling the method AlbumService.readAlbums() 16:05:42.409 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=1, title=quidem molestiae enim, userId=1) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=2, title=sunt qui excepturi placeat culpa, userId=1) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=3, title=omnis laborum odio, userId=1) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=4, title=non esse culpa molestiae omnis sed optio, userId=1) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=5, title=eaque aut omnis a, userId=1) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=6, title=natus impedit quibusdam illo est, userId=1) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=7, title=quibusdam autem aliquid et et quia, userId=1) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=8, title=qui fuga est a eum, userId=1) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=9, title=saepe unde necessitatibus rem, userId=1) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=10, title=distinctio laborum qui, userId=1) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=11, title=quam nostrum impedit mollitia quod et dolor, userId=2) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=12, title=consequatur autem doloribus natus consectetur, userId=2) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=13, title=ab rerum non rerum consequatur ut ea unde, userId=2) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=14, title=ducimus molestias eos animi atque nihil, userId=2) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=15, title=ut pariatur rerum ipsum natus repellendus praesentium, userId=2) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=16, title=voluptatem aut maxime inventore autem magnam atque repellat, userId=2) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=17, title=aut minima voluptatem ut velit, userId=2) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=18, title=nesciunt quia et doloremque, userId=2) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=19, title=velit pariatur quaerat similique libero omnis quia, userId=2) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=20, title=voluptas rerum iure ut enim, userId=2) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=21, title=repudiandae voluptatem optio est consequatur rem in temporibus et, userId=3) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=22, title=et rem non provident vel ut, userId=3) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=23, title=incidunt quisquam hic adipisci sequi, userId=3) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=24, title=dolores ut et facere placeat, userId=3) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=25, title=vero maxime id possimus sunt neque et consequatur, userId=3) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=26, title=quibusdam saepe ipsa vel harum, userId=3) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=27, title=id non nostrum expedita, userId=3) 16:05:42.410 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=28, title=omnis neque exercitationem sed dolor atque maxime aut cum, userId=3) 16:05:42.411 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=29, title=inventore ut quasi magnam itaque est fugit, userId=3) 16:05:42.411 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=30, title=tempora assumenda et similique odit distinctio error, userId=3) 16:05:42.411 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=31, title=adipisci laborum fuga laboriosam, userId=4) 16:05:42.411 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=32, title=reiciendis dolores a ut qui debitis non quo labore, userId=4) 16:05:42.411 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=33, title=iste eos nostrum, userId=4) 16:05:42.411 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=34, title=cumque voluptatibus rerum architecto blanditiis, userId=4) 16:05:42.411 [main] INFO com.iluwatar.dynamicproxy.App -- Album(id=35, title=et impedit nisi quae magni necessitatibus sed aut pariatur, userId=4) ```