├── .gitignore ├── README.md ├── pom.xml └── src ├── main └── java │ └── com │ └── braindevoiler │ └── designpattern │ ├── behavioral │ ├── chainofresponsibility │ │ └── ChainOfResponsibilityTest.java │ ├── command │ │ ├── Command.java │ │ ├── CommandTest.java │ │ ├── Light.java │ │ ├── LightOffCommand.java │ │ ├── LightOnCommand.java │ │ ├── NoCommand.java │ │ └── SimpleRemoteControl.java │ ├── interpreter │ │ └── InterpreterTest.java │ ├── iterator │ │ ├── DinerMenu.java │ │ ├── DinerMenuIterator.java │ │ ├── IteratorTest.java │ │ ├── Menu.java │ │ ├── MenuItem.java │ │ ├── PancakeHouseMenu.java │ │ └── Waitress.java │ ├── mediator │ │ └── MediatorTest.java │ ├── memento │ │ └── MementoTest.java │ ├── observer │ │ ├── CurrentConditionsDisplay.java │ │ ├── DisplayElement.java │ │ ├── ForecastDisplay.java │ │ ├── Observer.java │ │ ├── ObserverTest.java │ │ ├── Subject.java │ │ └── WeatherData.java │ ├── state │ │ ├── GumballMachine.java │ │ ├── HasQuarterState.java │ │ ├── NoQuarterState.java │ │ ├── SoldOutState.java │ │ ├── SoldState.java │ │ ├── State.java │ │ └── StateTest.java │ ├── strategy │ │ ├── Duck.java │ │ ├── FlyBehavior.java │ │ ├── FlyNoWay.java │ │ ├── FlyWithWings.java │ │ ├── MallardDuck.java │ │ ├── Quack.java │ │ ├── QuackBehavior.java │ │ ├── RedheadDuck.java │ │ ├── Squeak.java │ │ └── StrategyTest.java │ ├── template │ │ ├── CaffeineBeverage.java │ │ ├── Coffee.java │ │ ├── Tea.java │ │ └── TemplateTest.java │ └── visitor │ │ └── VisitorTest.java │ ├── creational │ ├── abstractfactory │ │ ├── AbstractFactoryTest.java │ │ ├── PizzaType.java │ │ ├── pizza │ │ │ ├── CheesePizza.java │ │ │ ├── ClamPizza.java │ │ │ ├── PepperoniPizza.java │ │ │ ├── Pizza.java │ │ │ └── VeggiePizza.java │ │ ├── pizzaingredient │ │ │ ├── Cheese.java │ │ │ ├── Clams.java │ │ │ ├── Dough.java │ │ │ ├── FreshClams.java │ │ │ ├── FrozenClams.java │ │ │ ├── MarinaraSauce.java │ │ │ ├── MozzarellaCheese.java │ │ │ ├── Pepperoni.java │ │ │ ├── PlumTomatoSauce.java │ │ │ ├── ReggianoCheese.java │ │ │ ├── Sauce.java │ │ │ ├── SlicedPepperoni.java │ │ │ ├── ThickCrustDough.java │ │ │ ├── ThinCrustDough.java │ │ │ └── Veggies.java │ │ ├── pizzaingredientfactory │ │ │ ├── ChicagoPizzaIngredientFactory.java │ │ │ ├── NYPizzaIngredientFactory.java │ │ │ └── PizzaIngredientFactory.java │ │ └── pizzastore │ │ │ ├── ChicagoPizzaStore.java │ │ │ ├── NYPizzaStore.java │ │ │ └── PizzaStore.java │ ├── builder │ │ ├── BuilderTest.java │ │ └── Computer.java │ ├── factorymethod │ │ ├── FactoryMethodTest.java │ │ ├── PizzaType.java │ │ ├── pizza │ │ │ ├── ChicagoStyleCheesePizza.java │ │ │ ├── ChicagoStyleClamPizza.java │ │ │ ├── ChicagoStylePepperoniPizza.java │ │ │ ├── ChicagoStyleVeggiePizza.java │ │ │ ├── NYStyleCheesePizza.java │ │ │ ├── NYStyleClamPizza.java │ │ │ ├── NYStylePepperoniPizza.java │ │ │ ├── NYStyleVeggiePizza.java │ │ │ └── Pizza.java │ │ └── pizzastore │ │ │ ├── ChicagoStylePizzaStore.java │ │ │ ├── NYStylePizzaStore.java │ │ │ └── PizzaStore.java │ ├── prototype │ │ ├── Employees.java │ │ └── PrototypeTest.java │ ├── simplefactory │ │ ├── PizzaStore.java │ │ ├── PizzaType.java │ │ ├── SimpleFactoryTest.java │ │ ├── SimplePizzaFactory.java │ │ └── pizza │ │ │ ├── CheesePizza.java │ │ │ ├── ClamPizza.java │ │ │ ├── PepperoniPizza.java │ │ │ ├── Pizza.java │ │ │ └── VeggiePizza.java │ └── singleton │ │ ├── Singleton.java │ │ └── SingletonTest.java │ └── structural │ ├── adapter │ ├── AdapterTest.java │ ├── Duck.java │ ├── MallardDuck.java │ ├── Turkey.java │ ├── TurkeyAdapter.java │ └── WildTurkey.java │ ├── bridge │ ├── BridgeTest.java │ ├── ConcreteRemote.java │ ├── RemoteControl.java │ ├── SamsungTv.java │ ├── SonyTv.java │ └── Tv.java │ ├── composite │ ├── CompositeTest.java │ ├── Menu.java │ ├── MenuComponent.java │ ├── MenuItem.java │ └── Waitress.java │ ├── decorator │ ├── Beverage.java │ ├── CondimentDecorator.java │ ├── DarkRoast.java │ ├── Decaf.java │ ├── DecoratorTest.java │ ├── Espresso.java │ ├── HouseBlend.java │ ├── Milk.java │ ├── Mocha.java │ ├── Soy.java │ └── Whip.java │ ├── facade │ ├── Amplifier.java │ ├── DvdPlayer.java │ ├── FacadeTest.java │ ├── HomeTheaterFacade.java │ ├── Projector.java │ ├── Screen.java │ └── TheaterLights.java │ ├── flyweight │ ├── Circle.java │ ├── FlyweightTest.java │ ├── Shape.java │ └── ShapeFactory.java │ └── proxy │ ├── GumballMachine.java │ ├── GumballMachineRemoteProxy.java │ ├── GumballMachineRemoteProxyTest.java │ ├── GumballMachineSetup.java │ └── machinestate │ ├── HasQuarterState.java │ ├── NoQuarterState.java │ ├── SoldOutState.java │ ├── SoldState.java │ └── State.java └── test └── java └── com └── braindevoiler └── designpattern └── AppTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | target/ 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Design Principles 2 | 3 | ### 1. Identify the aspects of your application that vary and separate them from what stays the same. 4 | * Take what varies and encapsulate it so it won't affect the rest of your code. 5 | * It results in fewer unintended consequences from code changes and more flexibility in your system. 6 | 7 | ### 2. Program to an interface, not an implementation. 8 | 9 | ### 3. Favor composition over inheritance. 10 | * It gives us more flexibility. 11 | * It lets us change behavior at runtime. 12 | 13 | ### 4. Strive for loosely coupled designs between objects that interact. 14 | * Loosely coupled designs allow us to build flexible OO systems that can handle change because they minimize the 15 | interdependency between objects. 16 | 17 | ### 5. The Open-Closed Principle 18 | * Classes should be open for extension, but closed for modification. 19 | * Allow classes to be easily extended to incorporate new behavior without modifying existing code. 20 | * Applying the Open-Closed Principle everywhere is wasteful, unnecessary, and can lead to complex, hard to understand 21 | code. We should concentrate on those areas that are most likely to change in the design. 22 | 23 | ### 6. The Dependency Inversion Principle 24 | * Depend upon abstractions. Do not depend upon concrete classes. 25 | * High level components should not depend on low-level components, rather, they should both depend on abstractions. 26 | * Guidelines: 27 | * No variable should hold a reference to a concrete class. 28 | * No class should derive from a concrete class. 29 | * No method should override an implemented method of any of its base classes. 30 | 31 | ### 7. The Principle of Least Knowledge/The Law of Demeter : Talk only to your immediate friends. 32 | * It means when you are designing a system, for any object, be careful of the number of classes it interacts with and 33 | also how it comes to interact with those classes. 34 | * This principle prevents us from creating designs that have a large number of classes coupled together so that 35 | changes in one part of the system cascade to other parts. 36 | * How do you keep from doing this? The principle provides some guidelines: take any object; now from any method in 37 | that object, the principle tells us that we should only invoke methods that belong to: 38 | * The object itself 39 | * Objects passed in as a parameter to the method 40 | * Any object the method creates or instantiates 41 | * Any components of the object (Object composition, has-a-relationship) 42 | * Above guidelines tells us not to call methods on objects that were returned from calling other methods. 43 | 44 | Without the principle: 45 | ``` 46 | public float getTemp() { 47 | Thermometer thermometer = station.getThermometer(); 48 | return thermometer.getTemperature(); 49 | } 50 | ``` 51 | 52 | With the principle: 53 | ``` 54 | public float getTemp() { 55 | return station.getTemperature(); 56 | } 57 | ``` 58 | 59 | #### Disadvantages of applying the Principle of Least Knowledge; 60 | * While the principle reduces the dependencies between objects and studies have shown this reduces software 61 | maintenance, it is also the case that applying this principle results in more "wrapper" classes being written to 62 | handle method calls to other components. This can result in increased complexity and development time as well as 63 | decreased runtime performance. 64 | 65 | ### 8. The Hollywoon Principle: Don't call us, we'll call you. (Template Method Pattern) 66 | * Allow low-level components to hook themselves into a system, but the high level components determine when they are 67 | needed, and how. 68 | * The high-level components give the low-level components a "don't call us, we'll call you" treatment. 69 | 70 | ### 9. Single Responsibility 71 | * A class should have only one reason to change. 72 | * Every responsibility of a class is an area of potential change. More than one responsibility means more than one 73 | area of change. 74 | * A class has high cohesion when it is designed around a set of related functions, and we say that it has low 75 | cohesion when it's designed around a set of unrelated functions. -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | com.braindevoiler 8 | design-patterns 9 | 1.0-SNAPSHOT 10 | 11 | design-patterns 12 | Project to learn Object Oriented Design Patterns 13 | https://github.com/braindevoiler/design-patterns 14 | 15 | 16 | MIT License 17 | https://opensource.org/licenses/MIT 18 | 19 | 20 | 21 | 22 | Ankur Gupta 23 | info@ankurgupta.net 24 | 25 | 26 | 27 | https://github.com/braindevoiler/design-patterns 28 | 29 | 30 | UTF-8 31 | 1.8 32 | 1.8 33 | 1.8 34 | 1.2.3 35 | 4.13.1 36 | 1.18.12 37 | 38 | 39 | 40 | 41 | junit 42 | junit 43 | ${junit.version} 44 | test 45 | 46 | 47 | ch.qos.logback 48 | logback-classic 49 | ${logback.version} 50 | 51 | 52 | org.projectlombok 53 | lombok 54 | ${lombok.version} 55 | provided 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/chainofresponsibility/ChainOfResponsibilityTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.chainofresponsibility; 2 | 3 | public class ChainOfResponsibilityTest { 4 | /** 5 | * With the Chain of Responsibility Pattern, you create a chain of objects that examine a request. Each object in 6 | * turn examines the request and handles it, or passes it on to the next object in the chain. 7 | *

8 | * Use the Chain of Responsibility Pattern when you want to give more than one object a chance to handle a request. 9 | *

10 | * Each object in the chain acts as a handler and has a successor object. If it can handle the request, it does; 11 | * otherwise, it forwards the request to its successor. 12 | *

13 | * It allows you to add or remove responsibilities dynamically by changing the members or order of the chain. 14 | *

15 | * Example: Spam filter rules in mailing application. 16 | */ 17 | public static void main(String[] args) { 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/command/Command.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.command; 2 | 3 | public interface Command { 4 | void execute(); 5 | 6 | void undo(); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/command/CommandTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.command; 2 | 3 | public class CommandTest { 4 | /** 5 | * The Command Pattern encapsulates a request as an object, thereby letting you parameterize other objects with 6 | * different requests, queue or log requests, and support undoable operations. 7 | */ 8 | public static void main(String[] args) { 9 | SimpleRemoteControl remote = new SimpleRemoteControl(); 10 | Light light = new Light(); 11 | Command lightOn = new LightOnCommand(light); 12 | Command lightOff = new LightOffCommand(light); 13 | remote.setCommand(0, lightOn, lightOff); 14 | remote.onButtonPressed(0); 15 | remote.offButtonPressed(0); 16 | remote.undoButtonPressed(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/command/Light.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.command; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class Light { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(Light.class); 9 | 10 | public void on() { 11 | LOGGER.info("Switching on light"); 12 | } 13 | 14 | public void off() { 15 | LOGGER.info("Switching off light"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/command/LightOffCommand.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.command; 2 | 3 | public class LightOffCommand implements Command { 4 | Light light; 5 | 6 | public LightOffCommand(Light light) { 7 | this.light = light; 8 | } 9 | 10 | public void execute() { 11 | light.off(); 12 | } 13 | 14 | public void undo() { 15 | light.on(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/command/LightOnCommand.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.command; 2 | 3 | public class LightOnCommand implements Command { 4 | Light light; 5 | 6 | public LightOnCommand(Light light) { 7 | this.light = light; 8 | } 9 | 10 | public void execute() { 11 | light.on(); 12 | } 13 | 14 | public void undo() { 15 | light.off(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/command/NoCommand.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.command; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class NoCommand implements Command { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(NoCommand.class); 9 | 10 | @Override 11 | public void execute() { 12 | LOGGER.info("Do Nothing"); 13 | } 14 | 15 | @Override 16 | public void undo() { 17 | LOGGER.info("Undo Nothing"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/command/SimpleRemoteControl.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.command; 2 | 3 | public class SimpleRemoteControl { 4 | private static final int COUNT_COMMANDS = 1; 5 | private final Command[] onCommands; 6 | private final Command[] offCommands; 7 | private Command undoCommand; 8 | 9 | public SimpleRemoteControl() { 10 | onCommands = new Command[COUNT_COMMANDS]; 11 | offCommands = new Command[COUNT_COMMANDS]; 12 | Command noCommand = new NoCommand(); 13 | for (int i = 0; i < COUNT_COMMANDS; i++) { 14 | onCommands[i] = noCommand; 15 | offCommands[i] = noCommand; 16 | } 17 | undoCommand = noCommand; 18 | } 19 | 20 | public void setCommand(int slot, Command onCommand, Command offCommand) { 21 | onCommands[slot] = onCommand; 22 | offCommands[slot] = offCommand; 23 | } 24 | 25 | public void onButtonPressed(int slot) { 26 | onCommands[slot].execute(); 27 | undoCommand = onCommands[slot]; 28 | } 29 | 30 | public void offButtonPressed(int slot) { 31 | offCommands[slot].execute(); 32 | undoCommand = offCommands[slot]; 33 | } 34 | 35 | public void undoButtonPressed() { 36 | undoCommand.undo(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/interpreter/InterpreterTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.interpreter; 2 | 3 | public class InterpreterTest { 4 | /** 5 | * Use the Interpreter Pattern to build an interpreter for a language. 6 | *

7 | * When you need to implement a simple language, the Interpreter Pattern defines a class-based representation for 8 | * its grammar along with an interpreter to interpret its sentences. To represent the language, you use a class 9 | * to represent each rule in the language. 10 | *

11 | * Representing each grammar rule in a class makes the language easy to implement. 12 | *

13 | * Because the grammar is represented by classes, you can easily change or extend the language. 14 | *

15 | * Appropriate when you have a simple grammar and simplicity is more important than efficiency. 16 | */ 17 | public static void main(String[] args) { 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/iterator/DinerMenu.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.iterator; 2 | 3 | import java.util.Iterator; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | 8 | public class DinerMenu implements Menu { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(DinerMenu.class); 10 | 11 | private static final int MAX_ITEMS = 6; 12 | private final MenuItem[] menuItems; 13 | private int numberOfItems = 0; 14 | 15 | public DinerMenu() { 16 | menuItems = new MenuItem[MAX_ITEMS]; 17 | 18 | addItem("Vegetarian BLT", 19 | "(Fakin') Bacon with lettuce & tomato on whole wheat", 20 | true, 2.99); 21 | addItem("BLT", 22 | "Bacon with lettuce & tomato on false wheat", 23 | true, 2.99); 24 | addItem("Soup of the day", 25 | "Soup of the day, with a side of potato salad", 26 | false, 3.29); 27 | addItem("Hotdog", 28 | "A hot dog, with a side of potato salad", 29 | false, 3.05); 30 | } 31 | 32 | public void addItem(String name, String description, boolean vegetarian, double price) { 33 | MenuItem menuItem = new MenuItem(name, description, vegetarian, price); 34 | if (numberOfItems >= MAX_ITEMS) { 35 | LOGGER.info("Sorry, menu is full! Can't add item to menu"); 36 | } else { 37 | menuItems[numberOfItems] = menuItem; 38 | numberOfItems = numberOfItems + 1; 39 | } 40 | } 41 | 42 | @Override 43 | public Iterator createIterator() { 44 | return new DinerMenuIterator(menuItems); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/iterator/DinerMenuIterator.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.iterator; 2 | 3 | import java.util.Iterator; 4 | import java.util.NoSuchElementException; 5 | 6 | 7 | public class DinerMenuIterator implements Iterator { 8 | private final MenuItem[] menuItems; 9 | private int currentIndex = 0; 10 | 11 | public DinerMenuIterator(MenuItem[] menuItems) { 12 | this.menuItems = menuItems; 13 | } 14 | 15 | @Override 16 | public boolean hasNext() { 17 | return currentIndex < menuItems.length && menuItems[currentIndex] != null; 18 | } 19 | 20 | @Override 21 | public MenuItem next() { 22 | if (currentIndex < menuItems.length) { 23 | MenuItem menuItem = menuItems[currentIndex]; 24 | currentIndex++; 25 | return menuItem; 26 | } else { 27 | throw new NoSuchElementException(""); 28 | } 29 | } 30 | 31 | @Override public void remove() { 32 | throw new UnsupportedOperationException("remove"); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/iterator/IteratorTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.iterator; 2 | 3 | public class IteratorTest { 4 | /** 5 | * The Iterator Pattern provides a way to access the elements of an aggregate object sequentially without 6 | * exposing its underlying representations. 7 | *

8 | * Iterator Pattern takes the responsibility of traversing elements and gives that responsibility to the iterator 9 | * object, not the aggregate object. 10 | */ 11 | public static void main(String args[]) { 12 | Waitress waitress = new Waitress(new PancakeHouseMenu(), new DinerMenu()); 13 | waitress.printBreakfastMenu(); 14 | waitress.printLunchMenu(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/iterator/Menu.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.iterator; 2 | 3 | import java.util.Iterator; 4 | 5 | 6 | public interface Menu { 7 | Iterator createIterator(); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/iterator/MenuItem.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.iterator; 2 | 3 | public class MenuItem { 4 | private final String name; 5 | private final String description; 6 | private final boolean vegetarian; 7 | private final double price; 8 | 9 | public MenuItem(String name, 10 | String description, 11 | boolean vegetarian, 12 | double price) { 13 | this.name = name; 14 | this.description = description; 15 | this.vegetarian = vegetarian; 16 | this.price = price; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public String getDescription() { 24 | return description; 25 | } 26 | 27 | public boolean isVegetarian() { 28 | return vegetarian; 29 | } 30 | 31 | public double getPrice() { 32 | return price; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return this.name + ",\n" + this.description + ",\n" + this.price + ",\n" + this.vegetarian + "\n"; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/iterator/PancakeHouseMenu.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.iterator; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | 6 | 7 | public class PancakeHouseMenu implements Menu { 8 | private final ArrayList menuItems; 9 | 10 | public PancakeHouseMenu() { 11 | menuItems = new ArrayList<>(); 12 | 13 | addItem("K&B's Pancake Breakfast", 14 | "Pancake with scrambled eggs, and toast", 15 | true, 2.99); 16 | addItem("Regular Pancake Breakfast", 17 | "Pancake with fried eggs, sausage", 18 | false, 2.99); 19 | addItem("Blueberry Pancake", 20 | "Pancake made with fresh blueberries", 21 | true, 3.49); 22 | addItem("Waffles", 23 | "Waffles, with your choice of blueberries or strawberries", 24 | true, 3.49); 25 | } 26 | 27 | public void addItem(String name, String description, boolean vegetarian, double price) { 28 | MenuItem menuItem = new MenuItem(name, description, vegetarian, price); 29 | menuItems.add(menuItem); 30 | } 31 | 32 | public Iterator createIterator() { 33 | return menuItems.iterator(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/iterator/Waitress.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.iterator; 2 | 3 | import java.util.Iterator; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | 8 | public class Waitress { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(Waitress.class); 10 | 11 | private final Menu pancakeHouseMenu; 12 | private final Menu dinerMenu; 13 | 14 | public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) { 15 | this.pancakeHouseMenu = pancakeHouseMenu; 16 | this.dinerMenu = dinerMenu; 17 | } 18 | 19 | private void printMenu(Iterator iterator) { 20 | while (iterator.hasNext()) { 21 | LOGGER.info(iterator.next().toString()); 22 | } 23 | } 24 | 25 | public void printBreakfastMenu() { 26 | Iterator breakfastItemsIterator = pancakeHouseMenu.createIterator(); 27 | LOGGER.info("\n\nPrinting Breakfast Menu:\n"); 28 | printMenu(breakfastItemsIterator); 29 | } 30 | 31 | public void printLunchMenu() { 32 | Iterator lunchItemsIterator = dinerMenu.createIterator(); 33 | LOGGER.info("\n\nPrinting Lunch Menu:\n"); 34 | printMenu(lunchItemsIterator); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/mediator/MediatorTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.mediator; 2 | 3 | public class MediatorTest { 4 | /** 5 | * Use the Mediator Pattern to centralize complex communications and control between related objects. 6 | *

7 | * It increases the re-usability of the objects supported by the Mediator by decoupling them from the system. 8 | *

9 | * Simplifies maintenance of the system by centralizing control logic. 10 | */ 11 | public static void main(String[] args) { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/memento/MementoTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.memento; 2 | 3 | public class MementoTest { 4 | /** 5 | * Use the Memento Pattern when you need to be able to return an object to one of its previous states. 6 | *

7 | * It is a good idea to keep the state that you are saving separate from the key object. 8 | * This separate object that holds the state is known as the Memento object. 9 | *

10 | * Keeping the saved state external from the key object helps to maintain the cohesion. 11 | */ 12 | public static void main(String[] args) { 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/observer/CurrentConditionsDisplay.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.observer; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class CurrentConditionsDisplay implements Observer, DisplayElement { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(CurrentConditionsDisplay.class); 9 | 10 | private float temperature; 11 | private float humidity; 12 | private final Subject weatherData; 13 | 14 | public CurrentConditionsDisplay(Subject weatherData) { 15 | this.weatherData = weatherData; 16 | weatherData.registerObserver(this); 17 | } 18 | 19 | @Override 20 | public void update(float temperature, float humidity, float pressure) { 21 | this.temperature = temperature; 22 | this.humidity = humidity; 23 | display(); 24 | } 25 | 26 | @Override 27 | public void display() { 28 | LOGGER.info("Current conditions: {} F degrees and {}% humidity", temperature, humidity); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/observer/DisplayElement.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.observer; 2 | 3 | public interface DisplayElement { 4 | void display(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/observer/ForecastDisplay.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.observer; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class ForecastDisplay implements Observer, DisplayElement { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(ForecastDisplay.class); 9 | 10 | private float temperature; 11 | private float humidity; 12 | private float pressure; 13 | private final Subject weatherData; 14 | 15 | public ForecastDisplay(Subject weatherData) { 16 | this.weatherData = weatherData; 17 | weatherData.registerObserver(this); 18 | } 19 | 20 | @Override 21 | public void update(float temperature, float humidity, float pressure) { 22 | this.temperature = temperature; 23 | this.humidity = humidity; 24 | this.pressure = pressure; 25 | display(); 26 | } 27 | 28 | @Override 29 | public void display() { 30 | LOGGER.info("Future conditions: {}F degrees and {}% humidity and {} bar", 31 | (temperature + 5), (humidity + 2), (pressure - 1)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/observer/Observer.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.observer; 2 | 3 | public interface Observer { 4 | void update(float temperature, float humidity, float pressure); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/observer/ObserverTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.observer; 2 | 3 | public class ObserverTest { 4 | /** 5 | * The Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, 6 | * all of its dependents are notified and updated automatically. 7 | *

8 | * The Observer Pattern provides an object design where subjects ond observers are loosely coupled. 9 | *

10 | * Java provides the Observer interface and the Observable class in the java.util package. 11 | */ 12 | public static void main(String[] args) { 13 | WeatherData weatherData = new WeatherData(); 14 | CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData); 15 | ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData); 16 | weatherData.setMeasurements(80, 65, 30.4f); 17 | weatherData.setMeasurements(82, 70, 29.2f); 18 | weatherData.setMeasurements(78, 90, 29.2f); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/observer/Subject.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.observer; 2 | 3 | public interface Subject { 4 | void registerObserver(Observer observer); 5 | 6 | void removeObserver(Observer observer); 7 | 8 | void notifyObservers(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/observer/WeatherData.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.observer; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | 7 | public class WeatherData implements Subject { 8 | 9 | private final List observers; 10 | private float temperature; 11 | private float humidity; 12 | private float pressure; 13 | 14 | public WeatherData() { 15 | observers = new ArrayList<>(); 16 | } 17 | 18 | @Override 19 | public void registerObserver(Observer observer) { 20 | observers.add(observer); 21 | } 22 | 23 | @Override 24 | public void removeObserver(Observer observer) { 25 | int i = observers.indexOf(observer); 26 | if (i > 0) { 27 | observers.remove(i); 28 | } 29 | } 30 | 31 | @Override 32 | public void notifyObservers() { 33 | for (Observer o : observers) { 34 | o.update(temperature, humidity, pressure); 35 | } 36 | } 37 | 38 | private void measurementsChanged() { 39 | notifyObservers(); 40 | } 41 | 42 | public void setMeasurements(float temperature, float humidity, float pressure) { 43 | this.temperature = temperature; 44 | this.humidity = humidity; 45 | this.pressure = pressure; 46 | measurementsChanged(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/state/GumballMachine.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.state; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class GumballMachine { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(GumballMachine.class); 9 | 10 | State soldOutState; 11 | State noQuarterState; 12 | State hasQuarterState; 13 | State soldState; 14 | 15 | State state; 16 | int count; 17 | 18 | public GumballMachine(int numberOfGumballs) { 19 | soldOutState = new SoldOutState(this); 20 | noQuarterState = new NoQuarterState(this); 21 | hasQuarterState = new HasQuarterState(this); 22 | soldState = new SoldState(this); 23 | this.count = numberOfGumballs; 24 | if (numberOfGumballs > 0) { 25 | state = noQuarterState; 26 | } else { 27 | state = soldOutState; 28 | } 29 | } 30 | 31 | public void insertQuarter() { 32 | state.insertQuarter(); 33 | } 34 | 35 | public void ejectQuarter() { 36 | state.ejectQuarter(); 37 | } 38 | 39 | public void turnCrank() { 40 | state.turnCrank(); 41 | state.dispense(); 42 | } 43 | 44 | public void setState(State state) { 45 | this.state = state; 46 | } 47 | 48 | void releaseBall() { 49 | LOGGER.info("A gumball comes rolling out the slot..."); 50 | if (count != 0) { 51 | count = count - 1; 52 | } 53 | } 54 | 55 | public State getSoldOutState() { 56 | return soldOutState; 57 | } 58 | 59 | public State getNoQuarterState() { 60 | return noQuarterState; 61 | } 62 | 63 | public State getHasQuarterState() { 64 | return hasQuarterState; 65 | } 66 | 67 | public State getSoldState() { 68 | return soldState; 69 | } 70 | 71 | public int getCount() { 72 | return count; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/state/HasQuarterState.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.state; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class HasQuarterState implements State { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(HasQuarterState.class); 9 | 10 | GumballMachine gumballMachine; 11 | 12 | public HasQuarterState(GumballMachine gumballMachine) { 13 | this.gumballMachine = gumballMachine; 14 | } 15 | 16 | @Override 17 | public void insertQuarter() { 18 | LOGGER.info("You can't insert another quarter"); 19 | } 20 | 21 | @Override 22 | public void ejectQuarter() { 23 | LOGGER.info("Quarter returned"); 24 | gumballMachine.setState(gumballMachine.getNoQuarterState()); 25 | } 26 | 27 | @Override 28 | public void turnCrank() { 29 | LOGGER.info("You turned..."); 30 | gumballMachine.setState(gumballMachine.getSoldState()); 31 | } 32 | 33 | @Override 34 | public void dispense() { 35 | LOGGER.info("No gumball dispensed"); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/state/NoQuarterState.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.state; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class NoQuarterState implements State { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(NoQuarterState.class); 9 | 10 | GumballMachine gumballMachine; 11 | 12 | public NoQuarterState(GumballMachine gumballMachine) { 13 | this.gumballMachine = gumballMachine; 14 | } 15 | 16 | @Override 17 | public void insertQuarter() { 18 | LOGGER.info("You inserted a quarter"); 19 | gumballMachine.setState(gumballMachine.getHasQuarterState()); 20 | } 21 | 22 | @Override 23 | public void ejectQuarter() { 24 | LOGGER.info("You haven't inserted a quarter"); 25 | } 26 | 27 | @Override 28 | public void turnCrank() { 29 | LOGGER.info("You turned, but there's no quarter"); 30 | } 31 | 32 | @Override 33 | public void dispense() { 34 | LOGGER.info("You need to pay first"); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/state/SoldOutState.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.state; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class SoldOutState implements State { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(SoldOutState.class); 9 | 10 | GumballMachine gumballMachine; 11 | 12 | public SoldOutState(GumballMachine gumballMachine) { 13 | this.gumballMachine = gumballMachine; 14 | } 15 | 16 | @Override 17 | public void insertQuarter() { 18 | LOGGER.info("You can't insert a quarter, the machine is sold out"); 19 | } 20 | 21 | @Override 22 | public void ejectQuarter() { 23 | LOGGER.info("You can't eject, you haven't inserted a quarter yet"); 24 | } 25 | 26 | @Override 27 | public void turnCrank() { 28 | LOGGER.info("You turned, but there are no gumballs"); 29 | } 30 | 31 | @Override 32 | public void dispense() { 33 | LOGGER.info("No gumball dispensed"); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/state/SoldState.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.state; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class SoldState implements State { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(SoldState.class); 9 | 10 | GumballMachine gumballMachine; 11 | 12 | public SoldState(GumballMachine gumballMachine) { 13 | this.gumballMachine = gumballMachine; 14 | } 15 | 16 | @Override 17 | public void insertQuarter() { 18 | LOGGER.info("Please wait, we're already giving you a gumball"); 19 | } 20 | 21 | @Override 22 | public void ejectQuarter() { 23 | LOGGER.info("Sorry, you already turned the crank"); 24 | } 25 | 26 | @Override 27 | public void turnCrank() { 28 | LOGGER.info("Turning twice doesn't get you another gumball"); 29 | } 30 | 31 | @Override 32 | public void dispense() { 33 | gumballMachine.releaseBall(); 34 | if (gumballMachine.getCount() > 0) { 35 | gumballMachine.setState(gumballMachine.getNoQuarterState()); 36 | } else { 37 | LOGGER.info("Oops, out of gumballs!"); 38 | gumballMachine.setState(gumballMachine.getSoldOutState()); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/state/State.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.state; 2 | 3 | public interface State { 4 | void insertQuarter(); 5 | 6 | void ejectQuarter(); 7 | 8 | void turnCrank(); 9 | 10 | void dispense(); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/state/StateTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.state; 2 | 3 | public class StateTest { 4 | /** 5 | * The State Pattern allows an object to alter its behavior when its internal state changes. The object will 6 | * appear to change its class. 7 | *

8 | * The pattern encapsulates state into separate classes and delegates to the object representing the current state. 9 | *

10 | * The class diagram of State pattern is same as of Strategy pattern. 11 | */ 12 | public static void main(String[] args) { 13 | GumballMachine gumballMachine = new GumballMachine(5); 14 | gumballMachine.insertQuarter(); 15 | gumballMachine.turnCrank(); 16 | gumballMachine.insertQuarter(); 17 | gumballMachine.turnCrank(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/strategy/Duck.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.strategy; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public abstract class Duck { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(Duck.class); 9 | 10 | private FlyBehavior flyBehavior; 11 | private QuackBehavior quackBehavior; 12 | 13 | public abstract void display(); 14 | 15 | public void fly() { 16 | flyBehavior.fly(); 17 | } 18 | 19 | public void quake() { 20 | quackBehavior.quack(); 21 | } 22 | 23 | public void swim() { 24 | LOGGER.info("Swimming..."); 25 | } 26 | 27 | public void setFlyBehavior(FlyBehavior flyBehavior) { 28 | this.flyBehavior = flyBehavior; 29 | } 30 | 31 | public void setQuackBehavior(QuackBehavior quackBehavior) { 32 | this.quackBehavior = quackBehavior; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/strategy/FlyBehavior.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.strategy; 2 | 3 | public interface FlyBehavior { 4 | void fly(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/strategy/FlyNoWay.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.strategy; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class FlyNoWay implements FlyBehavior { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(FlyNoWay.class); 9 | 10 | @Override 11 | public void fly() { 12 | LOGGER.info("I can't fly"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/strategy/FlyWithWings.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.strategy; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class FlyWithWings implements FlyBehavior { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(FlyWithWings.class); 9 | 10 | @Override 11 | public void fly() { 12 | LOGGER.info("I'm flying!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/strategy/MallardDuck.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.strategy; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class MallardDuck extends Duck { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(MallardDuck.class); 9 | 10 | public MallardDuck() { 11 | setQuackBehavior(new Quack()); 12 | setFlyBehavior(new FlyWithWings()); 13 | } 14 | 15 | @Override 16 | public void display() { 17 | LOGGER.info("Mallard Duck"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/strategy/Quack.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.strategy; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class Quack implements QuackBehavior { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(Quack.class); 9 | 10 | @Override 11 | public void quack() { 12 | LOGGER.info("Quack"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/strategy/QuackBehavior.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.strategy; 2 | 3 | public interface QuackBehavior { 4 | void quack(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/strategy/RedheadDuck.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.strategy; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class RedheadDuck extends Duck { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(RedheadDuck.class); 9 | 10 | public RedheadDuck() { 11 | setQuackBehavior(new Squeak()); 12 | setFlyBehavior(new FlyNoWay()); 13 | } 14 | 15 | @Override 16 | public void display() { 17 | LOGGER.info("ReadheadDuck"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/strategy/Squeak.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.strategy; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class Squeak implements QuackBehavior { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(Squeak.class); 9 | 10 | @Override 11 | public void quack() { 12 | LOGGER.info("Squeak"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/strategy/StrategyTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.strategy; 2 | 3 | public class StrategyTest { 4 | /** 5 | * The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. 6 | * Strategy lets the algorithm vary independently from clients that use it. 7 | */ 8 | public static void main(String args[]) { 9 | Duck mallard = new MallardDuck(); 10 | mallard.display(); 11 | mallard.quake(); 12 | mallard.swim(); 13 | mallard.fly(); 14 | 15 | Duck redheadDuck = new RedheadDuck(); 16 | redheadDuck.display(); 17 | redheadDuck.quake(); 18 | redheadDuck.swim(); 19 | redheadDuck.fly(); 20 | redheadDuck.setFlyBehavior(new FlyWithWings()); 21 | redheadDuck.setQuackBehavior(new Quack()); 22 | redheadDuck.swim(); 23 | redheadDuck.fly(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/template/CaffeineBeverage.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.template; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public abstract class CaffeineBeverage { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(CaffeineBeverage.class); 9 | 10 | public void prepareRecipe() { 11 | description(); 12 | boilWater(); 13 | brew(); 14 | pourInCup(); 15 | addCondiments(); 16 | } 17 | 18 | public abstract void description(); 19 | 20 | public abstract void brew(); 21 | 22 | public abstract void addCondiments(); 23 | 24 | public void boilWater() { 25 | LOGGER.info("Boiling water"); 26 | } 27 | 28 | public void pourInCup() { 29 | LOGGER.info("Pouring into cup"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/template/Coffee.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.template; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class Coffee extends CaffeineBeverage { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(Coffee.class); 9 | 10 | @Override 11 | public void description() { 12 | LOGGER.info("\n\nPreparing Coffee...\n"); 13 | } 14 | 15 | @Override 16 | public void brew() { 17 | LOGGER.info("Dripping Coffee through filter"); 18 | } 19 | 20 | @Override 21 | public void addCondiments() { 22 | LOGGER.info("Adding Sugar and Milk"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/template/Tea.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.template; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class Tea extends CaffeineBeverage { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(Tea.class); 9 | 10 | @Override 11 | public void description() { 12 | LOGGER.info("\n\nPreparing Tea...\n"); 13 | } 14 | 15 | @Override 16 | public void brew() { 17 | LOGGER.info("Steeping the tea"); 18 | } 19 | 20 | @Override 21 | public void addCondiments() { 22 | LOGGER.info("Adding Lemon"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/template/TemplateTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.template; 2 | 3 | public class TemplateTest { 4 | /** 5 | * The Template Method Pattern defines the skeleton of an algorithm in a method, deferring some steps to subclasses. 6 | * Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithms's 7 | * structure. 8 | */ 9 | public static void main(String[] args) { 10 | CaffeineBeverage tea = new Tea(); 11 | tea.prepareRecipe(); 12 | CaffeineBeverage coffee = new Coffee(); 13 | coffee.prepareRecipe(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/behavioral/visitor/VisitorTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.behavioral.visitor; 2 | 3 | public class VisitorTest { 4 | /** 5 | * Use the Visitor Pattern when you want to add capabilities to a composite of objects(Composition pattern) and 6 | * encapsulation is not important. 7 | *

8 | * It allows you to add operations to a Composite structure without changing the structure itself. 9 | *

10 | * Adding new operations is relatively easy. 11 | *

12 | * The code for operations performed by the Visitor is centralized. 13 | *

14 | * The Composite classes' encapsulation is broken when the Visitor is used. 15 | */ 16 | public static void main(String[] args) { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/AbstractFactoryTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory; 2 | 3 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzastore.NYPizzaStore; 4 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzastore.PizzaStore; 5 | 6 | 7 | public class AbstractFactoryTest { 8 | /** 9 | * The Abstract Factory Pattern provides an interface for creating families of related or dependent objects 10 | * without specifying their concrete classes. 11 | */ 12 | public static void main(String args[]) { 13 | PizzaStore pizzaStore = new NYPizzaStore(); 14 | pizzaStore.orderPizza(PizzaType.CHEESE); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/PizzaType.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory; 2 | 3 | public enum PizzaType { 4 | CHEESE, CLAM, PEPPERONI, VEGGIE 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizza/CheesePizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredientfactory.PizzaIngredientFactory; 6 | 7 | 8 | public class CheesePizza extends Pizza { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(CheesePizza.class); 10 | 11 | public CheesePizza(PizzaIngredientFactory pizzaIngredientFactory) { 12 | name = "Cheese"; 13 | this.pizzaIngredientFactory = pizzaIngredientFactory; 14 | } 15 | 16 | @Override 17 | public void prepare() { 18 | dough = pizzaIngredientFactory.createDough(); 19 | sauce = pizzaIngredientFactory.createSauce(); 20 | cheese = pizzaIngredientFactory.createCheese(); 21 | LOGGER.info("Preparing Cheese Pizza!"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizza/ClamPizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredientfactory.PizzaIngredientFactory; 6 | 7 | 8 | public class ClamPizza extends Pizza { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(ClamPizza.class); 10 | 11 | public ClamPizza(PizzaIngredientFactory pizzaIngredientFactory) { 12 | name = "Clam"; 13 | this.pizzaIngredientFactory = pizzaIngredientFactory; 14 | } 15 | 16 | @Override 17 | public void prepare() { 18 | dough = pizzaIngredientFactory.createDough(); 19 | sauce = pizzaIngredientFactory.createSauce(); 20 | cheese = pizzaIngredientFactory.createCheese(); 21 | clams = pizzaIngredientFactory.createClams(); 22 | LOGGER.info("Preparing Clam Pizza!"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizza/PepperoniPizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredientfactory.PizzaIngredientFactory; 6 | 7 | 8 | public class PepperoniPizza extends Pizza { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(PepperoniPizza.class); 10 | 11 | public PepperoniPizza(PizzaIngredientFactory pizzaIngredientFactory) { 12 | name = "Pepperoni"; 13 | this.pizzaIngredientFactory = pizzaIngredientFactory; 14 | } 15 | 16 | @Override 17 | public void prepare() { 18 | dough = pizzaIngredientFactory.createDough(); 19 | sauce = pizzaIngredientFactory.createSauce(); 20 | cheese = pizzaIngredientFactory.createCheese(); 21 | pepperoni = pizzaIngredientFactory.createPepperoni(); 22 | LOGGER.info("Preparing Pepperoni Pizza!"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizza/Pizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredientfactory.PizzaIngredientFactory; 6 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Cheese; 7 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Clams; 8 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Dough; 9 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Pepperoni; 10 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Sauce; 11 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Veggies; 12 | 13 | 14 | public abstract class Pizza { 15 | private static final Logger LOGGER = LoggerFactory.getLogger(Pizza.class); 16 | 17 | protected String name; 18 | protected Dough dough; 19 | protected Cheese cheese; 20 | protected Sauce sauce; 21 | protected Clams clams; 22 | protected Pepperoni pepperoni; 23 | protected Veggies[] veggies; 24 | 25 | protected PizzaIngredientFactory pizzaIngredientFactory; 26 | 27 | public abstract void prepare(); 28 | 29 | public void bake() { 30 | LOGGER.info("Baking {} Pizza!", name); 31 | } 32 | 33 | public void cut() { 34 | LOGGER.info("Cutting {} Pizza!", name); 35 | } 36 | 37 | public void box() { 38 | LOGGER.info("Boxing {} Pizza!", name); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizza/VeggiePizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredientfactory.PizzaIngredientFactory; 6 | 7 | 8 | public class VeggiePizza extends Pizza { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(VeggiePizza.class); 10 | 11 | public VeggiePizza(PizzaIngredientFactory pizzaIngredientFactory) { 12 | name = "Veggie"; 13 | this.pizzaIngredientFactory = pizzaIngredientFactory; 14 | } 15 | 16 | @Override 17 | public void prepare() { 18 | dough = pizzaIngredientFactory.createDough(); 19 | sauce = pizzaIngredientFactory.createSauce(); 20 | cheese = pizzaIngredientFactory.createCheese(); 21 | veggies = pizzaIngredientFactory.createVeggies(); 22 | LOGGER.info("Preparing Veggie Pizza!"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/Cheese.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public interface Cheese { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/Clams.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public interface Clams { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/Dough.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public interface Dough { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/FreshClams.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public class FreshClams implements Clams { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/FrozenClams.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public class FrozenClams implements Clams { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/MarinaraSauce.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public class MarinaraSauce implements Sauce { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/MozzarellaCheese.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public class MozzarellaCheese implements Cheese { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/Pepperoni.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public interface Pepperoni { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/PlumTomatoSauce.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public class PlumTomatoSauce implements Sauce { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/ReggianoCheese.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public class ReggianoCheese implements Cheese { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/Sauce.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public interface Sauce { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/SlicedPepperoni.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public class SlicedPepperoni implements Pepperoni { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/ThickCrustDough.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public class ThickCrustDough implements Dough { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/ThinCrustDough.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public class ThinCrustDough implements Dough { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredient/Veggies.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient; 2 | 3 | public class Veggies { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredientfactory/ChicagoPizzaIngredientFactory.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredientfactory; 2 | 3 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Cheese; 4 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Clams; 5 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Dough; 6 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.FrozenClams; 7 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Pepperoni; 8 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.PlumTomatoSauce; 9 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.ReggianoCheese; 10 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Sauce; 11 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.SlicedPepperoni; 12 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.ThinCrustDough; 13 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Veggies; 14 | 15 | 16 | public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory { 17 | @Override 18 | public Cheese createCheese() { 19 | return new ReggianoCheese(); 20 | } 21 | 22 | @Override 23 | public Clams createClams() { 24 | return new FrozenClams(); 25 | } 26 | 27 | @Override 28 | public Dough createDough() { 29 | return new ThinCrustDough(); 30 | } 31 | 32 | @Override 33 | public Sauce createSauce() { 34 | return new PlumTomatoSauce(); 35 | } 36 | 37 | @Override 38 | public Pepperoni createPepperoni() { 39 | return new SlicedPepperoni(); 40 | } 41 | 42 | @Override 43 | public Veggies[] createVeggies() { 44 | return null; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredientfactory/NYPizzaIngredientFactory.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredientfactory; 2 | 3 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Cheese; 4 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Clams; 5 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Dough; 6 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.FreshClams; 7 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.MarinaraSauce; 8 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.MozzarellaCheese; 9 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Pepperoni; 10 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Sauce; 11 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.SlicedPepperoni; 12 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.ThickCrustDough; 13 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Veggies; 14 | 15 | 16 | public class NYPizzaIngredientFactory implements PizzaIngredientFactory { 17 | @Override 18 | public Cheese createCheese() { 19 | return new MozzarellaCheese(); 20 | } 21 | 22 | @Override 23 | public Clams createClams() { 24 | return new FreshClams(); 25 | } 26 | 27 | @Override 28 | public Dough createDough() { 29 | return new ThickCrustDough(); 30 | } 31 | 32 | @Override 33 | public Sauce createSauce() { 34 | return new MarinaraSauce(); 35 | } 36 | 37 | @Override 38 | public Pepperoni createPepperoni() { 39 | return new SlicedPepperoni(); 40 | } 41 | 42 | @Override 43 | public Veggies[] createVeggies() { 44 | return null; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzaingredientfactory/PizzaIngredientFactory.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredientfactory; 2 | 3 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Cheese; 4 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Clams; 5 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Dough; 6 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Pepperoni; 7 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Sauce; 8 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredient.Veggies; 9 | 10 | 11 | public interface PizzaIngredientFactory { 12 | Dough createDough(); 13 | 14 | Sauce createSauce(); 15 | 16 | Cheese createCheese(); 17 | 18 | Clams createClams(); 19 | 20 | Pepperoni createPepperoni(); 21 | 22 | Veggies[] createVeggies(); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzastore/ChicagoPizzaStore.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzastore; 2 | 3 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredientfactory.ChicagoPizzaIngredientFactory; 4 | import com.braindevoiler.designpattern.creational.abstractfactory.pizza.PepperoniPizza; 5 | import com.braindevoiler.designpattern.creational.abstractfactory.PizzaType; 6 | import com.braindevoiler.designpattern.creational.abstractfactory.pizza.CheesePizza; 7 | import com.braindevoiler.designpattern.creational.abstractfactory.pizza.ClamPizza; 8 | import com.braindevoiler.designpattern.creational.abstractfactory.pizza.Pizza; 9 | import com.braindevoiler.designpattern.creational.abstractfactory.pizza.VeggiePizza; 10 | 11 | 12 | public class ChicagoPizzaStore extends PizzaStore { 13 | 14 | public ChicagoPizzaStore() { 15 | pizzaIngredientFactory = new ChicagoPizzaIngredientFactory(); 16 | } 17 | 18 | @Override 19 | protected Pizza createPizza(PizzaType pizzaType) { 20 | Pizza pizza; 21 | switch (pizzaType) { 22 | case CHEESE: 23 | pizza = new CheesePizza(pizzaIngredientFactory); 24 | break; 25 | case CLAM: 26 | pizza = new ClamPizza(pizzaIngredientFactory); 27 | break; 28 | case PEPPERONI: 29 | pizza = new PepperoniPizza(pizzaIngredientFactory); 30 | break; 31 | case VEGGIE: 32 | pizza = new VeggiePizza(pizzaIngredientFactory); 33 | break; 34 | default: 35 | throw new RuntimeException("Please give correct pizza type!"); 36 | } 37 | return pizza; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzastore/NYPizzaStore.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzastore; 2 | 3 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredientfactory.NYPizzaIngredientFactory; 4 | import com.braindevoiler.designpattern.creational.abstractfactory.pizza.PepperoniPizza; 5 | import com.braindevoiler.designpattern.creational.abstractfactory.PizzaType; 6 | import com.braindevoiler.designpattern.creational.abstractfactory.pizza.CheesePizza; 7 | import com.braindevoiler.designpattern.creational.abstractfactory.pizza.ClamPizza; 8 | import com.braindevoiler.designpattern.creational.abstractfactory.pizza.Pizza; 9 | import com.braindevoiler.designpattern.creational.abstractfactory.pizza.VeggiePizza; 10 | 11 | 12 | public class NYPizzaStore extends PizzaStore { 13 | 14 | public NYPizzaStore() { 15 | pizzaIngredientFactory = new NYPizzaIngredientFactory(); 16 | } 17 | 18 | @Override 19 | protected Pizza createPizza(PizzaType pizzaType) { 20 | Pizza pizza; 21 | switch (pizzaType) { 22 | case CHEESE: 23 | pizza = new CheesePizza(pizzaIngredientFactory); 24 | break; 25 | case CLAM: 26 | pizza = new ClamPizza(pizzaIngredientFactory); 27 | break; 28 | case PEPPERONI: 29 | pizza = new PepperoniPizza(pizzaIngredientFactory); 30 | break; 31 | case VEGGIE: 32 | pizza = new VeggiePizza(pizzaIngredientFactory); 33 | break; 34 | default: 35 | throw new RuntimeException("Please give correct pizza type!"); 36 | } 37 | return pizza; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/abstractfactory/pizzastore/PizzaStore.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.abstractfactory.pizzastore; 2 | 3 | import com.braindevoiler.designpattern.creational.abstractfactory.pizzaingredientfactory.PizzaIngredientFactory; 4 | import com.braindevoiler.designpattern.creational.abstractfactory.PizzaType; 5 | import com.braindevoiler.designpattern.creational.abstractfactory.pizza.Pizza; 6 | 7 | 8 | public abstract class PizzaStore { 9 | 10 | protected PizzaIngredientFactory pizzaIngredientFactory; 11 | 12 | protected abstract Pizza createPizza(PizzaType pizzaType); 13 | 14 | public Pizza orderPizza(PizzaType pizzaType) { 15 | Pizza pizza = createPizza(pizzaType); 16 | pizza.prepare(); 17 | pizza.bake(); 18 | pizza.cut(); 19 | pizza.box(); 20 | return pizza; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/builder/BuilderTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.builder; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class BuilderTest { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(BuilderTest.class); 9 | 10 | public static void main(String[] args) { 11 | Computer computer = Computer.builder() 12 | .cpu("Intel Quad Core") 13 | .motherBoard("Intel Mother Board") 14 | .ram("16 GB RAM") 15 | .hardDisk("1 TB HDD") 16 | .graphicsCardEnabled(true) 17 | .bluetoothEnabled(true) 18 | .build(); 19 | 20 | LOGGER.info("CPU: {}", computer.getCpu()); 21 | LOGGER.info("MotherBoard: {}", computer.getMotherBoard()); 22 | LOGGER.info("RAM: {}", computer.getRam()); 23 | LOGGER.info("Hard Disk: {}", computer.getHardDisk()); 24 | LOGGER.info("Is Graphics Card Enabled? {}", computer.isGraphicsCardEnabled()); 25 | LOGGER.info("Is Bluetooth Enabled? {}", computer.isBluetoothEnabled()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/builder/Computer.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.builder; 2 | 3 | import lombok.Getter; 4 | 5 | 6 | @Getter 7 | public class Computer { 8 | private final String cpu; 9 | private final String motherBoard; 10 | private final String ram; 11 | private final String hardDisk; 12 | private final boolean isGraphicsCardEnabled; 13 | private final boolean isBluetoothEnabled; 14 | 15 | private Computer(String cpu, String motherBoard, String ram, String hardDisk, 16 | boolean isGraphicsCardEnabled, boolean isBluetoothEnabled) { 17 | this.cpu = cpu; 18 | this.motherBoard = motherBoard; 19 | this.ram = ram; 20 | this.hardDisk = hardDisk; 21 | this.isGraphicsCardEnabled = isGraphicsCardEnabled; 22 | this.isBluetoothEnabled = isBluetoothEnabled; 23 | } 24 | 25 | public static ComputerBuilder builder() { 26 | return new ComputerBuilder(); 27 | } 28 | 29 | public static final class ComputerBuilder { 30 | private String cpu; 31 | private String motherBoard; 32 | private String ram; 33 | private String hardDisk; 34 | private boolean isGraphicsCardEnabled; 35 | private boolean isBluetoothEnabled; 36 | 37 | public ComputerBuilder cpu(String cpu) { 38 | this.cpu = cpu; 39 | return this; 40 | } 41 | 42 | public ComputerBuilder motherBoard(String motherBoard) { 43 | this.motherBoard = motherBoard; 44 | return this; 45 | } 46 | 47 | public ComputerBuilder ram(String ram) { 48 | this.ram = ram; 49 | return this; 50 | } 51 | 52 | public ComputerBuilder hardDisk(String hardDisk) { 53 | this.hardDisk = hardDisk; 54 | return this; 55 | } 56 | 57 | public ComputerBuilder graphicsCardEnabled(boolean isGraphicsCardEnabled) { 58 | this.isGraphicsCardEnabled = isGraphicsCardEnabled; 59 | return this; 60 | } 61 | 62 | public ComputerBuilder bluetoothEnabled(boolean isBluetoothEnabled) { 63 | this.isBluetoothEnabled = isBluetoothEnabled; 64 | return this; 65 | } 66 | 67 | public Computer build() { 68 | return new Computer(this.cpu, this.motherBoard, this.ram, this.hardDisk, 69 | this.isGraphicsCardEnabled, this.isBluetoothEnabled); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/FactoryMethodTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod; 2 | 3 | import com.braindevoiler.designpattern.creational.factorymethod.pizzastore.ChicagoStylePizzaStore; 4 | import com.braindevoiler.designpattern.creational.factorymethod.pizzastore.NYStylePizzaStore; 5 | import com.braindevoiler.designpattern.creational.factorymethod.pizzastore.PizzaStore; 6 | 7 | 8 | public class FactoryMethodTest { 9 | /** 10 | * The Factory Method Pattern defines an interface for creating an object, but lets subclasses decide which class 11 | * to instantiate. Factory method lets a class defer instantiation to subclasses. 12 | */ 13 | public static void main(String args[]) { 14 | PizzaStore nyStylePizzaStore = new NYStylePizzaStore(); 15 | PizzaStore chicagoStylePizzaStore = new ChicagoStylePizzaStore(); 16 | nyStylePizzaStore.orderPizza(PizzaType.CHEESE); 17 | chicagoStylePizzaStore.orderPizza(PizzaType.CHEESE); 18 | nyStylePizzaStore.orderPizza(PizzaType.CLAM); 19 | chicagoStylePizzaStore.orderPizza(PizzaType.CLAM); 20 | nyStylePizzaStore.orderPizza(PizzaType.PEPPERONI); 21 | chicagoStylePizzaStore.orderPizza(PizzaType.PEPPERONI); 22 | nyStylePizzaStore.orderPizza(PizzaType.VEGGIE); 23 | chicagoStylePizzaStore.orderPizza(PizzaType.VEGGIE); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/PizzaType.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod; 2 | 3 | public enum PizzaType { 4 | CHEESE, CLAM, PEPPERONI, VEGGIE 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/pizza/ChicagoStyleCheesePizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class ChicagoStyleCheesePizza extends Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(ChicagoStyleCheesePizza.class); 9 | 10 | @Override 11 | public void prepare() { 12 | LOGGER.info("Preparing Chicago style Cheese Pizza!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/pizza/ChicagoStyleClamPizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class ChicagoStyleClamPizza extends Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(ChicagoStyleClamPizza.class); 9 | 10 | @Override 11 | public void prepare() { 12 | LOGGER.info("Preparing Chicago style Clam Pizza!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/pizza/ChicagoStylePepperoniPizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class ChicagoStylePepperoniPizza extends Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(ChicagoStylePepperoniPizza.class); 9 | 10 | @Override 11 | public void prepare() { 12 | LOGGER.info("Preparing Chicago style Pepperoni Pizza!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/pizza/ChicagoStyleVeggiePizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class ChicagoStyleVeggiePizza extends Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(ChicagoStyleVeggiePizza.class); 9 | 10 | @Override 11 | public void prepare() { 12 | LOGGER.info("Preparing Chicago style Veggie Pizza!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/pizza/NYStyleCheesePizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class NYStyleCheesePizza extends Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(NYStyleCheesePizza.class); 9 | 10 | @Override 11 | public void prepare() { 12 | LOGGER.info("Preparing NY style Cheese Pizza!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/pizza/NYStyleClamPizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class NYStyleClamPizza extends Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(NYStyleClamPizza.class); 9 | 10 | @Override 11 | public void prepare() { 12 | LOGGER.info("Preparing NY style Clam Pizza!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/pizza/NYStylePepperoniPizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class NYStylePepperoniPizza extends Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(NYStylePepperoniPizza.class); 9 | 10 | @Override 11 | public void prepare() { 12 | LOGGER.info("Preparing NY style Pepperoni Pizza!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/pizza/NYStyleVeggiePizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class NYStyleVeggiePizza extends Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(NYStyleVeggiePizza.class); 9 | 10 | @Override 11 | public void prepare() { 12 | LOGGER.info("Preparing NY style Veggie Pizza!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/pizza/Pizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public abstract class Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(Pizza.class); 9 | 10 | public abstract void prepare(); 11 | 12 | public void bake() { 13 | LOGGER.info("Baking Pizza!"); 14 | } 15 | 16 | public void cut() { 17 | LOGGER.info("Cutting Pizza!"); 18 | } 19 | 20 | public void box() { 21 | LOGGER.info("Boxing Pizza!"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/pizzastore/ChicagoStylePizzaStore.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod.pizzastore; 2 | 3 | import com.braindevoiler.designpattern.creational.factorymethod.PizzaType; 4 | import com.braindevoiler.designpattern.creational.factorymethod.pizza.ChicagoStyleCheesePizza; 5 | import com.braindevoiler.designpattern.creational.factorymethod.pizza.ChicagoStyleClamPizza; 6 | import com.braindevoiler.designpattern.creational.factorymethod.pizza.ChicagoStylePepperoniPizza; 7 | import com.braindevoiler.designpattern.creational.factorymethod.pizza.ChicagoStyleVeggiePizza; 8 | import com.braindevoiler.designpattern.creational.factorymethod.pizza.Pizza; 9 | 10 | 11 | public class ChicagoStylePizzaStore extends PizzaStore { 12 | @Override 13 | protected Pizza createPizza(PizzaType pizzaType) { 14 | Pizza pizza; 15 | switch (pizzaType) { 16 | case CHEESE: 17 | pizza = new ChicagoStyleCheesePizza(); 18 | break; 19 | case CLAM: 20 | pizza = new ChicagoStyleClamPizza(); 21 | break; 22 | case PEPPERONI: 23 | pizza = new ChicagoStylePepperoniPizza(); 24 | break; 25 | case VEGGIE: 26 | pizza = new ChicagoStyleVeggiePizza(); 27 | break; 28 | default: 29 | throw new RuntimeException("Please give correct pizza type!"); 30 | } 31 | return pizza; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/pizzastore/NYStylePizzaStore.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod.pizzastore; 2 | 3 | import com.braindevoiler.designpattern.creational.factorymethod.PizzaType; 4 | import com.braindevoiler.designpattern.creational.factorymethod.pizza.NYStyleCheesePizza; 5 | import com.braindevoiler.designpattern.creational.factorymethod.pizza.NYStyleClamPizza; 6 | import com.braindevoiler.designpattern.creational.factorymethod.pizza.NYStylePepperoniPizza; 7 | import com.braindevoiler.designpattern.creational.factorymethod.pizza.Pizza; 8 | 9 | 10 | public class NYStylePizzaStore extends PizzaStore { 11 | 12 | @Override 13 | protected Pizza createPizza(PizzaType pizzaType) { 14 | Pizza pizza; 15 | switch (pizzaType) { 16 | case CHEESE: 17 | pizza = new NYStyleCheesePizza(); 18 | break; 19 | case CLAM: 20 | pizza = new NYStyleClamPizza(); 21 | break; 22 | case PEPPERONI: 23 | pizza = new NYStylePepperoniPizza(); 24 | break; 25 | case VEGGIE: 26 | pizza = new NYStylePepperoniPizza(); 27 | break; 28 | default: 29 | throw new RuntimeException("Please give correct pizza type!"); 30 | } 31 | return pizza; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/factorymethod/pizzastore/PizzaStore.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.factorymethod.pizzastore; 2 | 3 | import com.braindevoiler.designpattern.creational.factorymethod.PizzaType; 4 | import com.braindevoiler.designpattern.creational.factorymethod.pizza.Pizza; 5 | 6 | 7 | public abstract class PizzaStore { 8 | 9 | protected abstract Pizza createPizza(PizzaType pizzaType); 10 | 11 | public Pizza orderPizza(PizzaType pizzaType) { 12 | Pizza pizza = createPizza(pizzaType); 13 | pizza.prepare(); 14 | pizza.bake(); 15 | pizza.cut(); 16 | pizza.box(); 17 | return pizza; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/prototype/Employees.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.prototype; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | 9 | public class Employees implements Cloneable { 10 | private static final Logger LOGGER = LoggerFactory.getLogger(Employees.class); 11 | 12 | private final List empList; 13 | 14 | public Employees() { 15 | empList = new ArrayList<>(); 16 | } 17 | 18 | public Employees(List empList) { 19 | this.empList = empList; 20 | } 21 | 22 | public void loadData() { 23 | // Load data from DB 24 | empList.add("Ankur Gupta"); 25 | empList.add("Suresh Gupta"); 26 | empList.add("Sarita Gupta"); 27 | } 28 | 29 | public void printData() { 30 | for (String emp : this.empList) { 31 | LOGGER.info(emp); 32 | } 33 | } 34 | 35 | @Override 36 | protected Employees clone() throws CloneNotSupportedException { 37 | List tempList = new ArrayList<>(this.empList); 38 | return new Employees(tempList); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/prototype/PrototypeTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.prototype; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class PrototypeTest { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(PrototypeTest.class); 9 | 10 | /** 11 | * Use the Prototype Pattern when creating an instance of a given class is either expensive or complicated. 12 | *

13 | * It hides the complexities of making new instances from the client. 14 | *

15 | * In some circumstances, copying an object can be more efficient than creating a new object. 16 | */ 17 | public static void main(String args[]) { 18 | Employees employees = new Employees(); 19 | employees.loadData(); 20 | LOGGER.info("\nPrinting actual data:\n"); 21 | employees.printData(); 22 | try { 23 | Employees employeesClone = employees.clone(); 24 | LOGGER.info("\nPrinting cloned data:\n"); 25 | employeesClone.printData(); 26 | } catch (CloneNotSupportedException e) { 27 | LOGGER.error("Error in cloning.", e); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/simplefactory/PizzaStore.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.simplefactory; 2 | 3 | import com.braindevoiler.designpattern.creational.simplefactory.pizza.Pizza; 4 | 5 | 6 | public class PizzaStore { 7 | 8 | public Pizza orderPizza(PizzaType pizzaType) { 9 | Pizza pizza = SimplePizzaFactory.createPizza(pizzaType); 10 | pizza.prepare(); 11 | pizza.bake(); 12 | pizza.cut(); 13 | pizza.box(); 14 | return pizza; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/simplefactory/PizzaType.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.simplefactory; 2 | 3 | public enum PizzaType { 4 | CHEESE, CLAM, PEPPERONI, VEGGIE 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/simplefactory/SimpleFactoryTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.simplefactory; 2 | 3 | public class SimpleFactoryTest { 4 | 5 | public static void main(String args[]) { 6 | PizzaStore pizzaStore = new PizzaStore(); 7 | pizzaStore.orderPizza(PizzaType.CHEESE); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/simplefactory/SimplePizzaFactory.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.simplefactory; 2 | 3 | import com.braindevoiler.designpattern.creational.simplefactory.pizza.CheesePizza; 4 | import com.braindevoiler.designpattern.creational.simplefactory.pizza.ClamPizza; 5 | import com.braindevoiler.designpattern.creational.simplefactory.pizza.PepperoniPizza; 6 | import com.braindevoiler.designpattern.creational.simplefactory.pizza.Pizza; 7 | import com.braindevoiler.designpattern.creational.simplefactory.pizza.VeggiePizza; 8 | 9 | 10 | public class SimplePizzaFactory { 11 | public static Pizza createPizza(PizzaType pizzaType) { 12 | Pizza pizza; 13 | switch (pizzaType) { 14 | case CHEESE: 15 | pizza = new CheesePizza(); 16 | break; 17 | case CLAM: 18 | pizza = new ClamPizza(); 19 | break; 20 | case PEPPERONI: 21 | pizza = new PepperoniPizza(); 22 | break; 23 | case VEGGIE: 24 | pizza = new VeggiePizza(); 25 | break; 26 | default: 27 | throw new RuntimeException("Please give correct pizza type!"); 28 | } 29 | return pizza; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/simplefactory/pizza/CheesePizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.simplefactory.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class CheesePizza extends Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(CheesePizza.class); 9 | 10 | @Override 11 | public void prepare() { 12 | LOGGER.info("Preparing Cheese Pizza!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/simplefactory/pizza/ClamPizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.simplefactory.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class ClamPizza extends Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(ClamPizza.class); 9 | 10 | @Override 11 | public void prepare() { 12 | LOGGER.info("Preparing Clam Pizza!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/simplefactory/pizza/PepperoniPizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.simplefactory.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class PepperoniPizza extends Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(PepperoniPizza.class); 9 | 10 | @Override 11 | public void prepare() { 12 | LOGGER.info("Preparing Pepperoni Pizza!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/simplefactory/pizza/Pizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.simplefactory.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public abstract class Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(Pizza.class); 9 | 10 | public abstract void prepare(); 11 | 12 | public void bake() { 13 | LOGGER.info("Baking Pizza!"); 14 | } 15 | 16 | public void cut() { 17 | LOGGER.info("Cutting Pizza!"); 18 | } 19 | 20 | public void box() { 21 | LOGGER.info("Boxing Pizza!"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/simplefactory/pizza/VeggiePizza.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.simplefactory.pizza; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class VeggiePizza extends Pizza { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(VeggiePizza.class); 9 | 10 | @Override 11 | public void prepare() { 12 | LOGGER.info("Preparing Veggie Pizza!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/singleton/Singleton.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.singleton; 2 | 3 | public class Singleton { 4 | private volatile static Singleton instance; 5 | 6 | private Singleton() { 7 | } 8 | 9 | public static Singleton getInstance() { 10 | if (instance == null) { 11 | synchronized (Singleton.class) { 12 | // Double checked locking (Works in Java 5 or above) 13 | if (instance == null) { 14 | instance = new Singleton(); 15 | } 16 | } 17 | } 18 | return instance; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/creational/singleton/SingletonTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.creational.singleton; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class SingletonTest { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(SingletonTest.class); 9 | 10 | /* 11 | * The Singleton Pattern ensures a class has only one instance, and provides a global point of access to it. 12 | */ 13 | public static void main(String args[]) { 14 | Singleton singleton1 = Singleton.getInstance(); 15 | Singleton singleton2 = Singleton.getInstance(); 16 | LOGGER.info("Singleton1: {}", singleton1); 17 | LOGGER.info("Singleton2: {}", singleton2); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/adapter/AdapterTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.adapter; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class AdapterTest { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(AdapterTest.class); 9 | 10 | /** 11 | * The Adapter Pattern converts the interface of a class into another interface the clients expect. 12 | * Adapter lets classes work together that couldn't otherwise because of incompatible interfaces. 13 | *

14 | * Object composition is used to wrap the adaptee(Turkey) with an altered interface(Duck); 15 | * The advantage of this approach is that we can use an adapter with any subclass of the adaptee. 16 | */ 17 | public static void main(String args[]) { 18 | Duck duck = new MallardDuck(); 19 | Turkey turkey = new WildTurkey(); 20 | Duck turkeyAdapter = new TurkeyAdapter(new WildTurkey()); 21 | 22 | LOGGER.info("Duck says:"); 23 | duck.quack(); 24 | duck.fly(); 25 | 26 | LOGGER.info("\nTurkey says:"); 27 | turkey.gobble(); 28 | turkey.fly(); 29 | 30 | LOGGER.info("\nTurkeyAdapter says:"); 31 | turkeyAdapter.quack(); 32 | turkeyAdapter.fly(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/adapter/Duck.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.adapter; 2 | 3 | public interface Duck { 4 | void quack(); 5 | 6 | void fly(); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/adapter/MallardDuck.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.adapter; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class MallardDuck implements Duck { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(MallardDuck.class); 9 | 10 | @Override 11 | public void quack() { 12 | LOGGER.info("Quack"); 13 | } 14 | 15 | @Override 16 | public void fly() { 17 | LOGGER.info("I'm flying"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/adapter/Turkey.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.adapter; 2 | 3 | public interface Turkey { 4 | void gobble(); 5 | 6 | void fly(); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/adapter/TurkeyAdapter.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.adapter; 2 | 3 | public class TurkeyAdapter implements Duck { 4 | private final Turkey turkey; 5 | 6 | public TurkeyAdapter(Turkey turkey) { 7 | this.turkey = turkey; 8 | } 9 | 10 | @Override 11 | public void quack() { 12 | turkey.gobble(); 13 | } 14 | 15 | @Override 16 | public void fly() { 17 | for (int i = 0; i < 5; i++) { 18 | turkey.fly(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/adapter/WildTurkey.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.adapter; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class WildTurkey implements Turkey { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(WildTurkey.class); 9 | 10 | @Override 11 | public void gobble() { 12 | LOGGER.info("Gobble gobble"); 13 | } 14 | 15 | @Override 16 | public void fly() { 17 | LOGGER.info("I'm flying a short distance"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/bridge/BridgeTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.bridge; 2 | 3 | public class BridgeTest { 4 | /** 5 | * Use the Bridge Pattern to vary not only your implementations, but also your abstractions. It decouple an 6 | * abstraction from its implementation so that the two can vary independently. 7 | *

8 | * Implementation: Decompose the component's interface and implementation into orthogonal class hierarchies. The 9 | * interface class contains a pointer to the abstract implementation class. This pointer is initialized with an 10 | * instance of a concrete implementation class, but all subsequent interaction from the interface class to the 11 | * implementation class is limited to the abstraction maintained in the implementation base class. The client 12 | * interacts with the interface class, and it in turn "delegates" all requests to the implementation class. 13 | *

14 | * Benefits: 15 | * 1. It decouples an implementation so that it is not bound permanently to an interface. 16 | * 2. Abstraction and implementation can be extended independently. 17 | * 3. Changes to the concrete abstraction classes don't affect the client. 18 | * 4. Useful in graphic and windowing systems that need to run over multiple platforms. 19 | */ 20 | public static void main(String args[]) { 21 | Tv sonyTv = new SonyTv(); 22 | Tv samsungTv = new SamsungTv(); 23 | 24 | RemoteControl sonyTvOldRemote = new RemoteControl(sonyTv); 25 | RemoteControl samsungTvOldRemote = new RemoteControl(samsungTv); 26 | ConcreteRemote sonyTvNewRemote = new ConcreteRemote(sonyTv, 10); 27 | ConcreteRemote samsungTvNewRemote = new ConcreteRemote(samsungTv, 10); 28 | 29 | sonyTvOldRemote.on(); 30 | sonyTvOldRemote.setChannel(15); 31 | sonyTvOldRemote.off(); 32 | 33 | samsungTvOldRemote.on(); 34 | samsungTvOldRemote.setChannel(25); 35 | samsungTvOldRemote.off(); 36 | 37 | sonyTvNewRemote.on(); 38 | sonyTvNewRemote.nextChannel(); 39 | sonyTvNewRemote.previousChannel(); 40 | sonyTvNewRemote.off(); 41 | 42 | samsungTvNewRemote.on(); 43 | samsungTvNewRemote.nextChannel(); 44 | samsungTvNewRemote.previousChannel(); 45 | samsungTvNewRemote.off(); 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/bridge/ConcreteRemote.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.bridge; 2 | 3 | public class ConcreteRemote extends RemoteControl { 4 | 5 | int currentStation; 6 | 7 | public ConcreteRemote(Tv tv, int currentStation) { 8 | super(tv); 9 | this.currentStation = currentStation; 10 | } 11 | 12 | public void nextChannel() { 13 | currentStation++; 14 | setChannel(currentStation); 15 | } 16 | 17 | public void previousChannel() { 18 | currentStation--; 19 | setChannel(currentStation); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/bridge/RemoteControl.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.bridge; 2 | 3 | public class RemoteControl { 4 | private final Tv tv; 5 | 6 | public RemoteControl(Tv tv) { 7 | this.tv = tv; 8 | } 9 | 10 | public void on() { 11 | tv.on(); 12 | } 13 | 14 | public void off() { 15 | tv.off(); 16 | } 17 | 18 | public void setChannel(int channelNumber) { 19 | tv.tuneChannel(channelNumber); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/bridge/SamsungTv.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.bridge; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class SamsungTv extends Tv { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(SamsungTv.class); 9 | 10 | public void tuneChannel(int channelNumber) { 11 | LOGGER.info("Tuning to channel number {} on Samsung TV...", channelNumber); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/bridge/SonyTv.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.bridge; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class SonyTv extends Tv { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(SonyTv.class); 9 | 10 | public void tuneChannel(int channelNumber) { 11 | LOGGER.info("Tuning to channel number {} on Sony TV...", channelNumber); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/bridge/Tv.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.bridge; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public abstract class Tv { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(Tv.class); 9 | 10 | public void on() { 11 | LOGGER.info("Switching on TV..."); 12 | } 13 | 14 | public void off() { 15 | LOGGER.info("Switching off TV..."); 16 | } 17 | 18 | public abstract void tuneChannel(int channelNumber); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/composite/CompositeTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.composite; 2 | 3 | public class CompositeTest { 4 | /** 5 | * The Composite Pattern allows you to compose objects into tree structures to represent part-whole hierarchies. 6 | * Composite lets clients treat individual objects and composition of objects uniformly. 7 | *

8 | * Using a composite structure, we can apply the same operations over both composites and individual objects. 9 | */ 10 | public static void main(String args[]) { 11 | MenuComponent pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU", "Breakfast"); 12 | MenuComponent dinerMenu = new Menu("Diner MENU", "Lunch"); 13 | MenuComponent cafeMenu = new Menu("CAFE MENU", "Dinner"); 14 | MenuComponent dessertMenu = new Menu("DESSERT MENU", "Dessert of course"); 15 | 16 | MenuComponent allMenus = new Menu("ALL MENUS", "All menus combined"); 17 | allMenus.add(pancakeHouseMenu); 18 | allMenus.add(dinerMenu); 19 | allMenus.add(cafeMenu); 20 | dinerMenu.add(new MenuItem( 21 | "Pasta", 22 | "Spaghetti with Marinara Sauce, and a slice of sourdough bread", 23 | true, 24 | 3.89)); 25 | dinerMenu.add(dessertMenu); 26 | dessertMenu.add(new MenuItem( 27 | "Apple Pie", 28 | "Apple pie with a flakey crust, topped with vanilla icecream", 29 | true, 30 | 1.59)); 31 | Waitress waitress = new Waitress(allMenus); 32 | waitress.printMenu(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/composite/Menu.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.composite; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | 9 | public class Menu extends MenuComponent { 10 | private static final Logger LOGGER = LoggerFactory.getLogger(Menu.class); 11 | 12 | private final List menuComponents; 13 | private final String name; 14 | private final String description; 15 | 16 | public Menu(String name, String description) { 17 | this.name = name; 18 | this.description = description; 19 | menuComponents = new ArrayList<>(); 20 | } 21 | 22 | @Override 23 | public void add(MenuComponent menuComponent) { 24 | menuComponents.add(menuComponent); 25 | } 26 | 27 | public void print() { 28 | LOGGER.info(name); 29 | LOGGER.info(description); 30 | for (MenuComponent menuComponent : menuComponents) { 31 | menuComponent.print(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/composite/MenuComponent.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.composite; 2 | 3 | public abstract class MenuComponent { 4 | 5 | public void add(MenuComponent menuComponent) { 6 | throw new UnsupportedOperationException(); 7 | } 8 | 9 | public String getName() { 10 | throw new UnsupportedOperationException(); 11 | } 12 | 13 | public String getDescription() { 14 | throw new UnsupportedOperationException(); 15 | } 16 | 17 | public double getPrice() { 18 | throw new UnsupportedOperationException(); 19 | } 20 | 21 | public boolean isVegetarian() { 22 | throw new UnsupportedOperationException(); 23 | } 24 | 25 | public abstract void print(); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/composite/MenuItem.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.composite; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class MenuItem extends MenuComponent { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(MenuItem.class); 9 | 10 | private final String name; 11 | private final String description; 12 | private final boolean vegetarian; 13 | private final double price; 14 | 15 | public MenuItem(String name, 16 | String description, 17 | boolean vegetarian, 18 | double price) { 19 | this.name = name; 20 | this.description = description; 21 | this.vegetarian = vegetarian; 22 | this.price = price; 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | @Override 31 | public String getDescription() { 32 | return description; 33 | } 34 | 35 | @Override 36 | public boolean isVegetarian() { 37 | return vegetarian; 38 | } 39 | 40 | @Override 41 | public double getPrice() { 42 | return price; 43 | } 44 | 45 | public void print() { 46 | LOGGER.info("\n\nMenuItem Description: {}, {}, {}, {}\n", name, description, price, vegetarian); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/composite/Waitress.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.composite; 2 | 3 | public class Waitress { 4 | 5 | private final MenuComponent allMenus; 6 | 7 | public Waitress(MenuComponent allMenus) { 8 | this.allMenus = allMenus; 9 | } 10 | 11 | public void printMenu() { 12 | allMenus.print(); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/decorator/Beverage.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.decorator; 2 | 3 | public abstract class Beverage { 4 | 5 | protected String description; 6 | 7 | public String getDescription() { 8 | return description; 9 | } 10 | 11 | protected abstract double cost(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/decorator/CondimentDecorator.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.decorator; 2 | 3 | public abstract class CondimentDecorator extends Beverage { 4 | protected Beverage beverage; 5 | 6 | @Override 7 | public abstract String getDescription(); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/decorator/DarkRoast.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.decorator; 2 | 3 | public class DarkRoast extends Beverage { 4 | 5 | public DarkRoast() { 6 | description = "DarkRoast"; 7 | } 8 | 9 | @Override 10 | protected double cost() { 11 | return 10.0; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/decorator/Decaf.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.decorator; 2 | 3 | public class Decaf extends Beverage { 4 | 5 | public Decaf() { 6 | description = "Decaf"; 7 | } 8 | 9 | @Override 10 | protected double cost() { 11 | return 15.0; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/decorator/DecoratorTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.decorator; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class DecoratorTest { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(DecoratorTest.class); 9 | 10 | /** 11 | * The Decorator Pattern attaches additional responsibilities to an object dynamically. 12 | * Decorator provides a flexible alternative to subclassing for extending functionality. 13 | *

14 | * * Decorators have the same supertype as the objects they decorate. 15 | *

16 | * * You can use one or more decorators to wrap an object. 17 | *

18 | * * Given that the decorator has the same supertype as the object it decorates, we can pass around a decorated 19 | * object in place of the original(wrapped) object. 20 | *

21 | * * The decorator adds its own behavior either before and/or after delegating to the object it decorates to do the 22 | * rest of the job. 23 | *

24 | * * Objects can be decorated at any time, so we can decorate objects dynamically at runtime with as many 25 | * decorators as we like. 26 | *

27 | * java.io package is largely based on Decorator. 28 | */ 29 | public static void main(String args[]) { 30 | Beverage beverage = new Espresso(); 31 | LOGGER.info("{} {}", beverage.getDescription(), beverage.cost()); 32 | 33 | Beverage beverage2 = new DarkRoast(); 34 | beverage2 = new Mocha(beverage2); 35 | beverage2 = new Mocha(beverage2); 36 | beverage2 = new Whip(beverage2); 37 | LOGGER.info("{} {}", beverage2.getDescription(), beverage2.cost()); 38 | 39 | Beverage beverage3 = new HouseBlend(); 40 | beverage3 = new Soy(beverage3); 41 | beverage3 = new Mocha(beverage3); 42 | beverage3 = new Whip(beverage3); 43 | LOGGER.info("{} {}", beverage3.getDescription(), beverage3.cost()); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/decorator/Espresso.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.decorator; 2 | 3 | public class Espresso extends Beverage { 4 | 5 | public Espresso() { 6 | description = "Espresso"; 7 | } 8 | 9 | @Override 10 | protected double cost() { 11 | return 20.0; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/decorator/HouseBlend.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.decorator; 2 | 3 | public class HouseBlend extends Beverage { 4 | 5 | public HouseBlend() { 6 | description = "HouseBlend"; 7 | } 8 | 9 | @Override 10 | protected double cost() { 11 | return 25.0; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/decorator/Milk.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.decorator; 2 | 3 | public class Milk extends CondimentDecorator { 4 | 5 | public Milk(Beverage beverage) { 6 | this.beverage = beverage; 7 | } 8 | 9 | @Override 10 | public String getDescription() { 11 | return beverage.getDescription() + ", Milk"; 12 | } 13 | 14 | @Override 15 | protected double cost() { 16 | return 5.0 + beverage.cost(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/decorator/Mocha.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.decorator; 2 | 3 | public class Mocha extends CondimentDecorator { 4 | 5 | public Mocha(Beverage beverage) { 6 | this.beverage = beverage; 7 | } 8 | 9 | @Override 10 | public String getDescription() { 11 | return beverage.getDescription() + ", Mocha"; 12 | } 13 | 14 | @Override 15 | protected double cost() { 16 | return 8.0 + beverage.cost(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/decorator/Soy.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.decorator; 2 | 3 | public class Soy extends CondimentDecorator { 4 | 5 | public Soy(Beverage beverage) { 6 | this.beverage = beverage; 7 | } 8 | 9 | @Override 10 | public String getDescription() { 11 | return beverage.getDescription() + ", Soy"; 12 | } 13 | 14 | @Override 15 | protected double cost() { 16 | return 3.0 + beverage.cost(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/decorator/Whip.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.decorator; 2 | 3 | public class Whip extends CondimentDecorator { 4 | 5 | public Whip(Beverage beverage) { 6 | this.beverage = beverage; 7 | } 8 | 9 | @Override 10 | public String getDescription() { 11 | return beverage.getDescription() + ", Whip"; 12 | } 13 | 14 | @Override 15 | protected double cost() { 16 | return 10.0 + beverage.cost(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/facade/Amplifier.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.facade; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class Amplifier { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(Amplifier.class); 9 | 10 | public void on() { 11 | LOGGER.info("Amplifier on"); 12 | } 13 | 14 | public void off() { 15 | LOGGER.info("Amplifier off"); 16 | } 17 | 18 | public void setStereoSound() { 19 | LOGGER.info("Setting amplifier sound to stereo sound"); 20 | } 21 | 22 | public void setSurroundSound() { 23 | LOGGER.info("Setting amplifier sound to surround sound"); 24 | } 25 | 26 | public void setVolume(int volume) { 27 | LOGGER.info("Setting volume to {}", volume); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/facade/DvdPlayer.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.facade; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class DvdPlayer { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(DvdPlayer.class); 9 | 10 | private final Amplifier amplifier; 11 | private final Projector projector; 12 | 13 | public DvdPlayer(Amplifier amplifier, Projector projector) { 14 | this.amplifier = amplifier; 15 | this.projector = projector; 16 | } 17 | 18 | public void on() { 19 | LOGGER.info("Switching on Dvd Player..."); 20 | } 21 | 22 | public void off() { 23 | LOGGER.info("Switching off Dvd Player..."); 24 | } 25 | 26 | public void eject() { 27 | LOGGER.info("Ejecting Dvd..."); 28 | } 29 | 30 | public void pause() { 31 | LOGGER.info("Pausing movie..."); 32 | } 33 | 34 | public void stop() { 35 | LOGGER.info("Stopping movie..."); 36 | } 37 | 38 | public void play(String movie) { 39 | LOGGER.info("Playing movie {}", movie); 40 | } 41 | 42 | public void setSurroundAudio() { 43 | amplifier.setSurroundSound(); 44 | } 45 | 46 | public void setTwoChannelAudio() { 47 | amplifier.setStereoSound(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/facade/FacadeTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.facade; 2 | 3 | public class FacadeTest { 4 | 5 | /** 6 | * The Facade Pattern provides a unified interface to a set of interfaces in a subsystem. 7 | * Facade defines a higher level interface that makes the subsystem easier to use. 8 | *

9 | * In simple words, the Facade Pattern makes an interface simpler. 10 | * It makes a subsystem easier to use through a simplified interface. 11 | *

12 | * Facade Pattern allows us to avoid tight coupling between clients and subsystems. 13 | *

14 | * To use it, we create a class that simplifies and unifies a set of more complex classes that 15 | * belong to some subsystem. Client talks only with the Facade class for the functionality. 16 | */ 17 | public static void main(String args[]) { 18 | Screen screen = new Screen(); 19 | Amplifier amplifier = new Amplifier(); 20 | Projector projector = new Projector(); 21 | DvdPlayer dvdPlayer = new DvdPlayer(amplifier, projector); 22 | TheaterLights theaterLights = new TheaterLights(); 23 | HomeTheaterFacade homeTheater = new HomeTheaterFacade(amplifier, dvdPlayer, projector, theaterLights, screen); 24 | homeTheater.watchMovie("Judwaa"); 25 | homeTheater.endMovie(); 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/facade/HomeTheaterFacade.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.facade; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class HomeTheaterFacade { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(HomeTheaterFacade.class); 9 | 10 | private final Amplifier amplifier; 11 | private final DvdPlayer dvdPlayer; 12 | private final Projector projector; 13 | private final TheaterLights theaterLights; 14 | private final Screen screen; 15 | 16 | public HomeTheaterFacade(Amplifier amplifier, 17 | DvdPlayer dvdPlayer, 18 | Projector projector, 19 | TheaterLights theaterLights, 20 | Screen screen) { 21 | this.amplifier = amplifier; 22 | this.dvdPlayer = dvdPlayer; 23 | this.projector = projector; 24 | this.theaterLights = theaterLights; 25 | this.screen = screen; 26 | } 27 | 28 | public void watchMovie(String movie) { 29 | LOGGER.info("\n\nGet ready to watch a movie..."); 30 | theaterLights.dim(10); 31 | screen.down(); 32 | projector.on(); 33 | projector.wideScreenMode(); 34 | amplifier.on(); 35 | amplifier.setSurroundSound(); 36 | amplifier.setVolume(5); 37 | dvdPlayer.on(); 38 | dvdPlayer.play(movie); 39 | } 40 | 41 | public void endMovie() { 42 | LOGGER.info("\n\nShutting movie theater down..."); 43 | theaterLights.on(); 44 | screen.up(); 45 | projector.off(); 46 | amplifier.off(); 47 | dvdPlayer.stop(); 48 | dvdPlayer.eject(); 49 | dvdPlayer.off(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/facade/Projector.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.facade; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class Projector { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(Projector.class); 9 | 10 | public void on() { 11 | LOGGER.info("Switching on projector..."); 12 | } 13 | 14 | public void off() { 15 | LOGGER.info("Switching off projector..."); 16 | } 17 | 18 | public void wideScreenMode() { 19 | LOGGER.info("Setting wide screen mode on projector..."); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/facade/Screen.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.facade; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class Screen { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(Screen.class); 9 | 10 | public void up() { 11 | LOGGER.info("Setting screen up..."); 12 | } 13 | 14 | public void down() { 15 | LOGGER.info("Setting screen down..."); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/facade/TheaterLights.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.facade; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class TheaterLights { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(TheaterLights.class); 9 | 10 | public void on() { 11 | LOGGER.info("Switching on theater lights..."); 12 | } 13 | 14 | public void off() { 15 | LOGGER.info("Switching off theater lights..."); 16 | } 17 | 18 | public void dim(int level) { 19 | LOGGER.info("Settings theater lights to dim level {}", level); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/flyweight/Circle.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.flyweight; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | 7 | public class Circle implements Shape { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(Circle.class); 9 | 10 | private final String color; 11 | private int x; 12 | private int y; 13 | private int radius; 14 | 15 | public Circle(String color) { 16 | this.color = color; 17 | } 18 | 19 | public void setX(int x) { 20 | this.x = x; 21 | } 22 | 23 | public void setY(int y) { 24 | this.y = y; 25 | } 26 | 27 | public void setRadius(int radius) { 28 | this.radius = radius; 29 | } 30 | 31 | @Override 32 | public void draw() { 33 | LOGGER.info("Circle: Draw() [Color : {}, x : {}, y : {}, radius : {}", color, x, y, radius); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/flyweight/FlyweightTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.flyweight; 2 | 3 | public class FlyweightTest { 4 | private static final String[] colors = { "Red", "Green", "Blue", "White", "Black" }; 5 | 6 | /** 7 | * Flyweight pattern is used when one instance of a class can be used to provide many virtual instances. 8 | *

9 | * It reduces the number of object instances at runtime, saving memory. 10 | *

11 | * It centralizes state for many virtual objects into a single location. 12 | *

13 | * It is used when a class has many instances, and they can all be controlled identically. 14 | *

15 | * A drawback of the Flyweight pattern is that once you've implemented it, single, logical instances of the class 16 | * will not be able to behave independently from the other instances. 17 | *

18 | * Each "flyweight" object is divided into two pieces: the state-dependent (extrinsic) part, and the 19 | * state-independent (intrinsic) part. Intrinsic state is stored (shared) in the Flyweight object. Extrinsic 20 | * state is stored or computed by client objects, and passed to the Flyweight when its operations are invoked. 21 | *

22 | * Flyweights are stored in a Factory's repository. The client restrains herself from creating Flyweights 23 | * directly, and requests them from the Factory. Each Flyweight cannot stand on its own. Any attributes that 24 | * would make sharing impossible must be supplied by the client whenever a request is made of the Flyweight. 25 | *

26 | * Modern web browsers use this technique to prevent loading same images twice. When browser loads a web page, 27 | * it traverse through all images on that page. Browser loads all new images from Internet and places them the 28 | * internal cache. For already loaded images, a flyweight object is created, which has some unique data like 29 | * position within the page, but everything else is referenced to the cached one. 30 | */ 31 | public static void main(String[] args) { 32 | 33 | for (int i = 0; i < 20; ++i) { 34 | Circle circle = (Circle) ShapeFactory.getCircle(getRandomColor()); 35 | circle.setX(getRandomX()); 36 | circle.setY(getRandomY()); 37 | circle.setRadius(100); 38 | circle.draw(); 39 | } 40 | } 41 | 42 | private static String getRandomColor() { 43 | return colors[(int) (Math.random() * colors.length)]; 44 | } 45 | 46 | private static int getRandomX() { 47 | return (int) (Math.random() * 100); 48 | } 49 | 50 | private static int getRandomY() { 51 | return (int) (Math.random() * 100); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/flyweight/Shape.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.flyweight; 2 | 3 | public interface Shape { 4 | void draw(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/flyweight/ShapeFactory.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.flyweight; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | 9 | public class ShapeFactory { 10 | private static final Logger LOGGER = LoggerFactory.getLogger(ShapeFactory.class); 11 | 12 | private static final Map circleMap = new HashMap<>(); 13 | 14 | public static Shape getCircle(String color) { 15 | Circle circle = (Circle) circleMap.get(color); 16 | 17 | if (circle == null) { 18 | circle = new Circle(color); 19 | circleMap.put(color, circle); 20 | LOGGER.info("Creating circle of color : {}", color); 21 | } 22 | return circle; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/proxy/GumballMachine.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.proxy; 2 | 3 | import java.rmi.RemoteException; 4 | import java.rmi.server.UnicastRemoteObject; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import com.braindevoiler.designpattern.structural.proxy.machinestate.HasQuarterState; 8 | import com.braindevoiler.designpattern.structural.proxy.machinestate.NoQuarterState; 9 | import com.braindevoiler.designpattern.structural.proxy.machinestate.SoldOutState; 10 | import com.braindevoiler.designpattern.structural.proxy.machinestate.SoldState; 11 | import com.braindevoiler.designpattern.structural.proxy.machinestate.State; 12 | import lombok.Getter; 13 | 14 | 15 | @Getter 16 | public class GumballMachine extends UnicastRemoteObject implements GumballMachineRemoteProxy { 17 | private static final Logger LOGGER = LoggerFactory.getLogger(GumballMachine.class); 18 | 19 | private final State soldOutState; 20 | private final State noQuarterState; 21 | private final State hasQuarterState; 22 | private final State soldState; 23 | 24 | private State state; 25 | private int count; 26 | private final String location; 27 | 28 | public GumballMachine(int numberOfGumballs, String location) throws RemoteException { 29 | soldOutState = new SoldOutState(this); 30 | noQuarterState = new NoQuarterState(this); 31 | hasQuarterState = new HasQuarterState(this); 32 | soldState = new SoldState(this); 33 | this.count = numberOfGumballs; 34 | if (numberOfGumballs > 0) { 35 | state = noQuarterState; 36 | } else { 37 | state = soldOutState; 38 | } 39 | this.location = location; 40 | } 41 | 42 | @Override 43 | public void insertQuarter() { 44 | state.insertQuarter(); 45 | } 46 | 47 | @Override 48 | public void ejectQuarter() { 49 | state.ejectQuarter(); 50 | } 51 | 52 | @Override 53 | public void turnCrank() { 54 | state.turnCrank(); 55 | state.dispense(); 56 | } 57 | 58 | public void setState(State state) { 59 | this.state = state; 60 | } 61 | 62 | public void releaseBall() { 63 | LOGGER.info("A gumball comes rolling out the slot..."); 64 | if (count != 0) { 65 | count = count - 1; 66 | } 67 | } 68 | 69 | @Override 70 | public void report() { 71 | LOGGER.info("Gumball Machine: {}", this.getLocation()); 72 | LOGGER.info("Current inventory: {} gumballs", this.getCount()); 73 | LOGGER.info("Current state: {}", this.getState()); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/proxy/GumballMachineRemoteProxy.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.proxy; 2 | 3 | import java.rmi.Remote; 4 | import java.rmi.RemoteException; 5 | 6 | 7 | public interface GumballMachineRemoteProxy extends Remote { 8 | 9 | void insertQuarter() throws RemoteException; 10 | 11 | void ejectQuarter() throws RemoteException; 12 | 13 | void turnCrank() throws RemoteException; 14 | 15 | void report() throws RemoteException; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/proxy/GumballMachineRemoteProxyTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.proxy; 2 | 3 | import java.rmi.Naming; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | 8 | public class GumballMachineRemoteProxyTest { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(GumballMachineRemoteProxyTest.class); 10 | 11 | /** 12 | * The Proxy Pattern provides a surrogate or placeholder for another object to control access to it. Use the 13 | * Proxy Pattern to create a representative object that controls access to another object, which may be 14 | * remote, expensive to create or in need of securing. The following are the different kinds of proxies: 15 | *

16 | * 1. Remote Proxy: A remote proxy controls access to a remote object. 17 | *

18 | * 2. Virtual Proxy: A virtual proxy controls access to a resource that is expensive to create. The virtual 19 | * proxy often defers the creation of the object until it is needed. The virtual proxy also acts as a surrogate 20 | * for the object before and while it is being created. After that, the proxy delegates requests directly to the 21 | * RealSubject. 22 | *

23 | * 3. Caching Proxy: A caching proxy maintains a cache of previously created objects and when a request is 24 | * made it returns cached objects, if possible. 25 | *

26 | * 4. Protection Proxy: A protection proxy controls access to a resource based on access rights. 27 | */ 28 | public static void main(String[] args) { 29 | try { 30 | String location = "rmi://127.0.0.1:9099/gumballmachine"; 31 | GumballMachineRemoteProxy remoteProxyMachine = (GumballMachineRemoteProxy) Naming.lookup(location); 32 | remoteProxyMachine.report(); 33 | remoteProxyMachine.insertQuarter(); 34 | remoteProxyMachine.turnCrank(); 35 | remoteProxyMachine.turnCrank(); 36 | remoteProxyMachine.ejectQuarter(); 37 | remoteProxyMachine.report(); 38 | } catch (Exception e) { 39 | LOGGER.error("Error:", e); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/proxy/GumballMachineSetup.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.proxy; 2 | 3 | import java.rmi.Naming; 4 | import java.rmi.registry.LocateRegistry; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | 9 | public class GumballMachineSetup { 10 | private static final Logger LOGGER = LoggerFactory.getLogger(GumballMachineSetup.class); 11 | 12 | public static void main(String[] args) { 13 | int count = 10; 14 | String location = "127.0.0.1"; 15 | int port = 9099; 16 | try { 17 | GumballMachine machine = new GumballMachine(count, location); 18 | LocateRegistry.createRegistry(port); 19 | Naming.rebind("//" + location + ":" + port + "/gumballmachine", machine); 20 | machine.report(); 21 | } catch (Exception e) { 22 | LOGGER.error("Error:", e); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/proxy/machinestate/HasQuarterState.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.proxy.machinestate; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import com.braindevoiler.designpattern.structural.proxy.GumballMachine; 6 | 7 | 8 | public class HasQuarterState implements State { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(HasQuarterState.class); 10 | 11 | GumballMachine gumballMachine; 12 | 13 | public HasQuarterState(GumballMachine gumballMachine) { 14 | this.gumballMachine = gumballMachine; 15 | } 16 | 17 | @Override 18 | public void insertQuarter() { 19 | LOGGER.info("You can't insert another quarter"); 20 | } 21 | 22 | @Override 23 | public void ejectQuarter() { 24 | LOGGER.info("Quarter returned"); 25 | gumballMachine.setState(gumballMachine.getNoQuarterState()); 26 | } 27 | 28 | @Override 29 | public void turnCrank() { 30 | LOGGER.info("You turned..."); 31 | gumballMachine.setState(gumballMachine.getSoldState()); 32 | } 33 | 34 | @Override 35 | public void dispense() { 36 | LOGGER.info("No gumball dispensed"); 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "HasQuarterState"; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/proxy/machinestate/NoQuarterState.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.proxy.machinestate; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import com.braindevoiler.designpattern.structural.proxy.GumballMachine; 6 | 7 | 8 | public class NoQuarterState implements State { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(NoQuarterState.class); 10 | 11 | // @transient will make sure that this field won't be serialized. 12 | transient GumballMachine gumballMachine; 13 | 14 | public NoQuarterState(GumballMachine gumballMachine) { 15 | this.gumballMachine = gumballMachine; 16 | } 17 | 18 | @Override 19 | public void insertQuarter() { 20 | LOGGER.info("You inserted a quarter"); 21 | gumballMachine.setState(gumballMachine.getHasQuarterState()); 22 | } 23 | 24 | @Override 25 | public void ejectQuarter() { 26 | LOGGER.info("You haven't inserted a quarter"); 27 | } 28 | 29 | @Override 30 | public void turnCrank() { 31 | LOGGER.info("You turned, but there's no quarter"); 32 | } 33 | 34 | @Override 35 | public void dispense() { 36 | LOGGER.info("You need to pay first"); 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "NoQuarterState"; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/proxy/machinestate/SoldOutState.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.proxy.machinestate; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import com.braindevoiler.designpattern.structural.proxy.GumballMachine; 6 | 7 | 8 | public class SoldOutState implements State { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(SoldOutState.class); 10 | 11 | GumballMachine gumballMachine; 12 | 13 | public SoldOutState(GumballMachine gumballMachine) { 14 | this.gumballMachine = gumballMachine; 15 | } 16 | 17 | @Override 18 | public void insertQuarter() { 19 | LOGGER.info("You can't insert a quarter, the machine is sold out"); 20 | } 21 | 22 | @Override 23 | public void ejectQuarter() { 24 | LOGGER.info("You can't eject, you haven't inserted a quarter yet"); 25 | } 26 | 27 | @Override 28 | public void turnCrank() { 29 | LOGGER.info("You turned, but there are no gumballs"); 30 | } 31 | 32 | @Override 33 | public void dispense() { 34 | LOGGER.info("No gumball dispensed"); 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "SoldOutState"; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/proxy/machinestate/SoldState.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.proxy.machinestate; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import com.braindevoiler.designpattern.structural.proxy.GumballMachine; 6 | 7 | 8 | public class SoldState implements State { 9 | private static final Logger LOGGER = LoggerFactory.getLogger(SoldState.class); 10 | 11 | GumballMachine gumballMachine; 12 | 13 | public SoldState(GumballMachine gumballMachine) { 14 | this.gumballMachine = gumballMachine; 15 | } 16 | 17 | @Override 18 | public void insertQuarter() { 19 | LOGGER.info("Please wait, we're already giving you a gumball"); 20 | } 21 | 22 | @Override 23 | public void ejectQuarter() { 24 | LOGGER.info("Sorry, you already turned the crank"); 25 | } 26 | 27 | @Override 28 | public void turnCrank() { 29 | LOGGER.info("Turning twice doesn't get you another gumball"); 30 | } 31 | 32 | @Override 33 | public void dispense() { 34 | gumballMachine.releaseBall(); 35 | if (gumballMachine.getCount() > 0) { 36 | gumballMachine.setState(gumballMachine.getNoQuarterState()); 37 | } else { 38 | LOGGER.info("Oops, out of gumballs!"); 39 | gumballMachine.setState(gumballMachine.getSoldOutState()); 40 | } 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "SoldState"; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/braindevoiler/designpattern/structural/proxy/machinestate/State.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern.structural.proxy.machinestate; 2 | 3 | import java.io.Serializable; 4 | 5 | 6 | // Serialization is needed to transfer state over network. 7 | public interface State extends Serializable { 8 | void insertQuarter(); 9 | 10 | void ejectQuarter(); 11 | 12 | void turnCrank(); 13 | 14 | void dispense(); 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/braindevoiler/designpattern/AppTest.java: -------------------------------------------------------------------------------- 1 | package com.braindevoiler.designpattern; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | import org.junit.Test; 5 | 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest { 11 | /** 12 | * Rigorous Test :-) 13 | */ 14 | @Test 15 | public void shouldAnswerWithTrue() { 16 | assertTrue(true); 17 | } 18 | } 19 | --------------------------------------------------------------------------------