├── .gitignore ├── README.md ├── Singleton_test.txt ├── pom.xml └── src └── main └── java └── dev └── atanu └── design ├── behavioral ├── chain │ └── responsibility │ │ ├── Atm100RupeesDispenser.java │ │ ├── Atm200RupeesDispenser.java │ │ ├── Atm500RupeesDispenser.java │ │ ├── AtmDispenseChain.java │ │ ├── AtmWithdrawl.java │ │ ├── AtmWithdrawlTest.java │ │ └── Currency.java ├── command │ ├── CloseFileCommand.java │ ├── CommandDesignTest.java │ ├── FileCommand.java │ ├── FileOperationInvoker.java │ ├── FileReceiver.java │ ├── OpenFileCommand.java │ ├── ReadFileCommand.java │ ├── SaveFileCommand.java │ ├── TextFile.java │ ├── WordFile.java │ └── WriteFileCommand.java ├── interpreter │ ├── AuthenticationFilter.java │ ├── DebugFilter.java │ ├── Filter.java │ ├── FilterChain.java │ ├── FilterManager.java │ ├── RequestHandler.java │ ├── RequestHandlerTest.java │ └── Target.java ├── iterator │ ├── Collection.java │ ├── Iterator.java │ ├── Notification.java │ ├── NotificationBar.java │ ├── NotificationBarTest.java │ ├── NotificationCollection.java │ └── NotificationIterator.java ├── mediator │ ├── ChatBox.java │ ├── ChatBoxImpl.java │ ├── ChatClientTest.java │ ├── User.java │ └── UserImpl.java ├── memento │ ├── Article.java │ ├── ArticleMemento.java │ └── MementoTest.java ├── observer │ ├── CurrentConditionsDisplay.java │ ├── DisplayElement.java │ ├── Observer.java │ ├── ObserverPatternTest.java │ ├── Subject.java │ └── WeatherData.java ├── state │ ├── DeliveredState.java │ ├── DeliveryState.java │ ├── OrderedState.java │ ├── Package.java │ ├── ShippingState.java │ ├── State.java │ └── StatePatternTest.java ├── strategy │ ├── CreditCard.java │ ├── CreditCardPayStrategy.java │ ├── Item.java │ ├── NetBankingDetails.java │ ├── NetBankingPayStrategy.java │ ├── PaymentStrategy.java │ ├── ShoppingCart.java │ ├── ShoppingCartTest.java │ ├── UpiDetails.java │ └── UpiPayStrategy.java ├── template │ └── method │ │ ├── GlassHouse.java │ │ ├── HouseTemplate.java │ │ ├── TemplateMethodPatternTest.java │ │ └── WoodenHouse.java └── visitor │ ├── Element.java │ ├── ElementVisitor.java │ ├── JsonElement.java │ ├── Visitor.java │ ├── VisitorTest.java │ ├── XmlElement.java │ └── YmlElement.java ├── creational ├── builder │ ├── Computer.java │ ├── ComputerBuilderTest.java │ ├── ComputerProcessor.java │ └── ComputerRAM.java ├── factory │ ├── asbtract │ │ ├── AbstractFactory.java │ │ ├── AbstractFactoryTest.java │ │ ├── AndroidMobileFactory.java │ │ ├── FactoryProvider.java │ │ ├── IPhone14.java │ │ ├── IPhone15.java │ │ ├── IPhoneMobileFactory.java │ │ ├── Mobile.java │ │ ├── MotorolaMobile.java │ │ ├── RealmeMobile.java │ │ └── SamsungMobile.java │ └── method │ │ ├── ChicagoPizzaStore.java │ │ ├── ChicagoStyleChickenPizza.java │ │ ├── ChicagoStyleVeggiePizza.java │ │ ├── FactoryMethodTest.java │ │ ├── NYPizzaStore.java │ │ ├── NYStyleChickenPizza.java │ │ ├── NYStyleVeggiePizza.java │ │ ├── Pizza.java │ │ └── PizzaStore.java ├── prototype │ ├── Prototype.java │ ├── PrototypeTest.java │ ├── StudentAddress.java │ └── StudentRecord.java └── singleton │ ├── MySingleton.java │ ├── SingletonTest.java │ └── SingletonThread.java └── structural ├── adapter ├── AdapterPatternTest.java ├── Socket.java ├── SocketAdapter.java ├── SocketClassAdapterImpl.java ├── SocketObjectAdapterImpl.java └── Volt.java ├── bridge ├── BridgePatternTest.java ├── Color.java ├── GreenColor.java ├── Rectangle.java ├── RedColor.java ├── Shape.java └── Triangle.java ├── composite ├── BusinessAnalyst.java ├── CompositePatternTest.java ├── Developer.java ├── Employee.java ├── Manager.java └── Tester.java ├── decorator ├── CheeseDecorator.java ├── ChickenSandwich.java ├── SaladDecorator.java ├── Sandwich.java ├── SandwichDecorator.java ├── SandwichMakerTest.java └── VegSandwich.java ├── facade ├── CardDetails.java ├── DeliveryAddress.java ├── DeliveryService.java ├── FacadePatternTest.java ├── Operator.java ├── OrderService.java ├── PaymentService.java └── Product.java ├── flyweight ├── Brush.java ├── BrushFactory.java ├── BrushSize.java ├── FlyweightPatternTest.java ├── MediumBrush.java ├── ThickBrush.java └── ThinBrush.java └── proxy ├── InternetAccess.java ├── ProxyInternetAccess.java ├── ProxyPatternClientTest.java └── RealInternetAccess.java /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | log/ 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | # Compiled class file 14 | *.class 15 | 16 | # Log file 17 | *.log 18 | 19 | # BlueJ files 20 | *.ctxt 21 | 22 | # Mobile Tools for Java (J2ME) 23 | .mtj.tmp/ 24 | 25 | # Package Files # 26 | *.jar 27 | *.war 28 | *.nar 29 | *.ear 30 | *.zip 31 | *.tar.gz 32 | *.rar 33 | 34 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 35 | hs_err_pid* 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Java Design Pattern 2 | Java design patterns are divided into three categories - behavioral, creational and structural design patterns. 3 | 4 | ### Behavioral Design Pattern 5 | There are eleven behavioral design patterns: 6 | - Chain Responsibility 7 | - Command Pattern 8 | - Interpreter 9 | - Iterator 10 | - Mediator 11 | - Memento 12 | - Observer 13 | - State 14 | - Strategy 15 | - Template Method 16 | - Visitor 17 | 18 | ### Creational Design Pattern 19 | There are five creational design patterns: 20 | - Builder 21 | - Abstract Factory 22 | - Factory Method 23 | - Prototype 24 | - Singleton 25 | 26 | ### Structural Design Pattern 27 | There are seven structural design patterns: 28 | - Adapter 29 | - Bridge 30 | - Composite 31 | - Decorator 32 | - Facade 33 | - Flyweight 34 | - Proxy 35 | 36 | ## Getting Started 37 | This repository is created to have a quick references of those design patterns. 38 | ### Running the Application 39 | Classes for each design pattern are placed to its own package. There is a Test class (name ends with Test) in each package with a main() method to run and verify respective design pattern. 40 | 41 | ## Declaration 42 | There are blogs/tutorials where the design patterns are fully explained. For quick reference the URLs are provided in each Test class documentation. If any code is taken from any tutorial/blog, that URL is also mentioned in Test class documentation and the credit goes to the respective owner. Mentioning few websites to learn the design patterns: 43 | - [Digital Ocean](https://www.digitalocean.com/community/tutorials/java-design-patterns-example-tutorial) 44 | - [Refactoring Guru](https://refactoring.guru/design-patterns/java) 45 | - [GeeksForGeeks](https://www.geeksforgeeks.org) 46 | - [HowToDoInJava](https://howtodoinjava.com/design-patterns/) 47 | - [Baeldung](https://www.baeldung.com/) 48 | 49 | #### ************************************************ Happy Learning ************************************************ 50 | -------------------------------------------------------------------------------- /Singleton_test.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atanubhowmick/design-pattern-project/6b11a0cfa3bcf6e08f2d96d2472486a412154ff2/Singleton_test.txt -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | dev.atanu.ds 7 | design-pattern-project 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | design-pattern-project 12 | http://maven.apache.org 13 | 14 | 15 | 1.8 16 | 1.8 17 | 1.8 18 | UTF-8 19 | 20 | 21 | 22 | 23 | junit 24 | junit 25 | 3.8.1 26 | test 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/chain/responsibility/Atm100RupeesDispenser.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.chain.responsibility; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Atm100RupeesDispenser implements AtmDispenseChain { 11 | 12 | private AtmDispenseChain chain; 13 | 14 | private static final int AMOUNT = 100; 15 | 16 | @Override 17 | public void setNextChain(AtmDispenseChain nextChain) { 18 | this.chain = nextChain; 19 | } 20 | 21 | @Override 22 | public void dispense(Currency currency) { 23 | if (currency.getAmount() >= AMOUNT) { 24 | int num = currency.getAmount() / AMOUNT; 25 | int remainder = currency.getAmount() % AMOUNT; 26 | System.out.println("Dispensing " + num + " of " + AMOUNT + " rupees note"); 27 | if (remainder != 0) { 28 | this.chain.dispense(new Currency(remainder)); 29 | } 30 | } else { 31 | throw new IllegalArgumentException("Invalid amount: " + AMOUNT); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/chain/responsibility/Atm200RupeesDispenser.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.chain.responsibility; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Atm200RupeesDispenser implements AtmDispenseChain { 11 | 12 | private AtmDispenseChain chain; 13 | 14 | private static final int AMOUNT = 200; 15 | 16 | @Override 17 | public void setNextChain(AtmDispenseChain nextChain) { 18 | this.chain = nextChain; 19 | } 20 | 21 | @Override 22 | public void dispense(Currency currency) { 23 | if (currency.getAmount() >= AMOUNT) { 24 | int num = currency.getAmount() / AMOUNT; 25 | int remainder = currency.getAmount() % AMOUNT; 26 | System.out.println("Dispensing " + num + " of " + AMOUNT + " rupees note"); 27 | if (remainder != 0) { 28 | this.chain.dispense(new Currency(remainder)); 29 | } 30 | } else { 31 | this.chain.dispense(currency); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/chain/responsibility/Atm500RupeesDispenser.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.chain.responsibility; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Atm500RupeesDispenser implements AtmDispenseChain { 11 | 12 | private AtmDispenseChain chain; 13 | 14 | private static final int AMOUNT = 500; 15 | 16 | @Override 17 | public void setNextChain(AtmDispenseChain nextChain) { 18 | this.chain = nextChain; 19 | } 20 | 21 | @Override 22 | public void dispense(Currency currency) { 23 | if (currency.getAmount() >= AMOUNT) { 24 | int num = currency.getAmount() / AMOUNT; 25 | int remainder = currency.getAmount() % AMOUNT; 26 | System.out.println("Dispensing " + num + " of " + AMOUNT + " rupees note"); 27 | if (remainder != 0) { 28 | this.chain.dispense(new Currency(remainder)); 29 | } 30 | } else { 31 | this.chain.dispense(currency); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/chain/responsibility/AtmDispenseChain.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.chain.responsibility; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface AtmDispenseChain { 11 | 12 | public void setNextChain(AtmDispenseChain nextChain); 13 | 14 | public void dispense(Currency cur); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/chain/responsibility/AtmWithdrawl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.chain.responsibility; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class AtmWithdrawl { 11 | 12 | private AtmDispenseChain c1; 13 | 14 | public AtmWithdrawl() { 15 | // initialize the chain 16 | this.c1 = new Atm500RupeesDispenser(); 17 | AtmDispenseChain c2 = new Atm200RupeesDispenser(); 18 | AtmDispenseChain c3 = new Atm100RupeesDispenser(); 19 | 20 | // set the chain of responsibility 21 | c1.setNextChain(c2); 22 | c2.setNextChain(c3); 23 | } 24 | 25 | public void withdraw(int amount) { 26 | if (amount % 100 != 0) { 27 | throw new IllegalArgumentException("Withdrawl amount must be a multiple of 100"); 28 | } 29 | 30 | c1.dispense(new Currency(amount)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/chain/responsibility/AtmWithdrawlTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.chain.responsibility; 5 | 6 | /** 7 | * https://www.digitalocean.com/community/tutorials/chain-of-responsibility-design-pattern-in-java 8 | * 9 | * @author Atanu Bhowmick 10 | * 11 | */ 12 | public class AtmWithdrawlTest { 13 | 14 | public static void main(String[] args) { 15 | AtmWithdrawl atmWithdrawl = new AtmWithdrawl(); 16 | 17 | System.out.println("---- First Withdrawl ----"); 18 | atmWithdrawl.withdraw(2500); 19 | 20 | System.out.println("---- Second Withdrawl ----"); 21 | atmWithdrawl.withdraw(1800); 22 | 23 | System.out.println("---- Third Withdrawl ----"); 24 | atmWithdrawl.withdraw(2250); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/chain/responsibility/Currency.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.chain.responsibility; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Currency { 11 | 12 | private int amount; 13 | 14 | public Currency(int amount) { 15 | this.amount = amount; 16 | } 17 | 18 | public int getAmount() { 19 | return this.amount; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/command/CloseFileCommand.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.command; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class CloseFileCommand implements FileCommand { 11 | 12 | private FileReceiver fileReceiver; 13 | 14 | public CloseFileCommand(FileReceiver fileReceiver) { 15 | this.fileReceiver = fileReceiver; 16 | } 17 | 18 | @Override 19 | public String execute() { 20 | System.out.println("Inside CloseFileCommand"); 21 | fileReceiver.close(); 22 | return "File closed"; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return "Command to close file : " + fileReceiver; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/command/CommandDesignTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.command; 5 | 6 | /** 7 | * https://www.baeldung.com/java-command-pattern 8 | * https://www.digitalocean.com/community/tutorials/command-design-pattern 9 | * 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public class CommandDesignTest { 14 | 15 | public static void main(String[] args) { 16 | 17 | FileReceiver textFile = new TextFile("Test.txt"); 18 | FileReceiver wordFile = new WordFile("Info.docs"); 19 | 20 | // Text file commands. 21 | FileOperationInvoker invoker = new FileOperationInvoker(); 22 | 23 | invoker.setCommand(new OpenFileCommand(textFile)); 24 | System.out.println(invoker.executeOperation()); 25 | 26 | invoker.setCommand(new ReadFileCommand(textFile)); 27 | System.out.println(invoker.executeOperation()); 28 | 29 | invoker.setCommand(new WriteFileCommand(textFile)); 30 | System.out.println(invoker.executeOperation()); 31 | 32 | invoker.setCommand(new SaveFileCommand(textFile)); 33 | System.out.println(invoker.executeOperation()); 34 | 35 | invoker.setCommand(new CloseFileCommand(textFile)); 36 | System.out.println(invoker.executeOperation()); 37 | 38 | System.out.println("**************************"); 39 | 40 | // Word file command. Executing only selected commands. 41 | invoker.setCommand(new OpenFileCommand(wordFile)); 42 | System.out.println(invoker.executeOperation()); 43 | 44 | invoker.setCommand(new ReadFileCommand(wordFile)); 45 | System.out.println(invoker.executeOperation()); 46 | 47 | invoker.setCommand(new CloseFileCommand(wordFile)); 48 | System.out.println(invoker.executeOperation()); 49 | 50 | // Printing history 51 | System.out.println("********History*******"); 52 | invoker.getHistory().forEach(System.out :: println); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/command/FileCommand.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.command; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface FileCommand { 11 | 12 | String execute(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/command/FileOperationInvoker.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.command; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public class FileOperationInvoker { 14 | 15 | private List history = new ArrayList<>(); 16 | 17 | private FileCommand command; 18 | 19 | public String executeOperation() { 20 | if (command == null) { 21 | throw new IllegalStateException("Command is not set"); 22 | } 23 | history.add(command); 24 | return command.execute(); 25 | } 26 | 27 | public void setCommand(FileCommand command) { 28 | this.command = command; 29 | } 30 | 31 | public List getHistory() { 32 | return history; 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/command/FileReceiver.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.command; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface FileReceiver { 11 | 12 | public String open(); 13 | 14 | public String read(); 15 | 16 | public String write(); 17 | 18 | public String save(); 19 | 20 | public void close(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/command/OpenFileCommand.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.command; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class OpenFileCommand implements FileCommand { 11 | 12 | private FileReceiver fileReceiver; 13 | 14 | public OpenFileCommand(FileReceiver fileReceiver) { 15 | this.fileReceiver = fileReceiver; 16 | } 17 | 18 | @Override 19 | public String execute() { 20 | System.out.println("Inside OpenFileCommand"); 21 | return fileReceiver.open(); 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "Command to open file : " + fileReceiver; 27 | } 28 | 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/command/ReadFileCommand.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.command; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ReadFileCommand implements FileCommand { 11 | 12 | private FileReceiver fileReceiver; 13 | 14 | public ReadFileCommand(FileReceiver fileReceiver) { 15 | this.fileReceiver = fileReceiver; 16 | } 17 | 18 | @Override 19 | public String execute() { 20 | System.out.println("Inside ReadFileCommand"); 21 | return fileReceiver.read(); 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "Command to read file : " + fileReceiver; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/command/SaveFileCommand.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.command; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class SaveFileCommand implements FileCommand { 11 | 12 | private FileReceiver fileReceiver; 13 | 14 | public SaveFileCommand(FileReceiver fileReceiver) { 15 | this.fileReceiver = fileReceiver; 16 | } 17 | 18 | @Override 19 | public String execute() { 20 | System.out.println("Inside SaveFileCommand"); 21 | return fileReceiver.save(); 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "Command to save file : " + fileReceiver; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/command/TextFile.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.command; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class TextFile implements FileReceiver { 11 | 12 | private final String fileName; 13 | 14 | public TextFile(String fileName) { 15 | this.fileName = fileName; 16 | } 17 | 18 | @Override 19 | public String open() { 20 | return "Opening text file: " + fileName; 21 | } 22 | 23 | @Override 24 | public String read() { 25 | return "Reading text file: " + fileName; 26 | } 27 | 28 | @Override 29 | public String write() { 30 | return "Writing to text file: " + fileName; 31 | } 32 | 33 | @Override 34 | public String save() { 35 | return "Saving text file: " + fileName; 36 | } 37 | 38 | @Override 39 | public void close() { 40 | System.out.println("Closing text file: " + fileName); 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "TextFile[" + fileName + "]"; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/command/WordFile.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.command; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class WordFile implements FileReceiver { 11 | 12 | private final String fileName; 13 | 14 | public WordFile(String fileName) { 15 | this.fileName = fileName; 16 | } 17 | 18 | @Override 19 | public String open() { 20 | return "Opening word file: " + fileName; 21 | } 22 | 23 | @Override 24 | public String read() { 25 | return "Reading word file: " + fileName; 26 | } 27 | 28 | @Override 29 | public String write() { 30 | return "Writing to word file: " + fileName; 31 | } 32 | 33 | @Override 34 | public String save() { 35 | return "Saving word file: " + fileName; 36 | } 37 | 38 | @Override 39 | public void close() { 40 | System.out.println("Closing word file: " + fileName); 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "WordFile[" + fileName + "]"; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/command/WriteFileCommand.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.command; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class WriteFileCommand implements FileCommand { 11 | 12 | private FileReceiver fileReceiver; 13 | 14 | public WriteFileCommand(FileReceiver fileReceiver) { 15 | this.fileReceiver = fileReceiver; 16 | } 17 | 18 | @Override 19 | public String execute() { 20 | System.out.println("Inside WriteFileCommand"); 21 | return fileReceiver.write(); 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "Command to write file : " + fileReceiver; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/interpreter/AuthenticationFilter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.interpreter; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class AuthenticationFilter implements Filter{ 11 | 12 | @Override 13 | public void doFilter(String request) { 14 | System.out.println("Authenticating request: " + request); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/interpreter/DebugFilter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.interpreter; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class DebugFilter implements Filter{ 11 | 12 | @Override 13 | public void doFilter(String request) { 14 | System.out.println("Logging request : " + request); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/interpreter/Filter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.interpreter; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface Filter { 11 | 12 | public void doFilter(String request); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/interpreter/FilterChain.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.interpreter; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public class FilterChain { 14 | 15 | private List filters; 16 | private Target target; 17 | 18 | public FilterChain() { 19 | filters = new ArrayList(); 20 | } 21 | 22 | public void addFilter(Filter filter) { 23 | filters.add(filter); 24 | } 25 | 26 | public void execute(String request) { 27 | for (Filter filter : filters) { 28 | filter.doFilter(request); 29 | } 30 | target.execute(request); 31 | } 32 | 33 | public void setTarget(Target target) { 34 | this.target = target; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/interpreter/FilterManager.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.interpreter; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class FilterManager { 11 | 12 | private FilterChain filterChain; 13 | 14 | public FilterManager(Target target) { 15 | filterChain = new FilterChain(); 16 | filterChain.setTarget(target); 17 | } 18 | 19 | public void setFilter(Filter filter) { 20 | filterChain.addFilter(filter); 21 | } 22 | 23 | public void filterRequest(String request) { 24 | filterChain.execute(request); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/interpreter/RequestHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.interpreter; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class RequestHandler { 11 | 12 | private FilterManager filterManager; 13 | 14 | public void setFilterManager(FilterManager filterManager) { 15 | this.filterManager = filterManager; 16 | 17 | } 18 | 19 | public void handleRequest(String request) { 20 | filterManager.filterRequest(request); 21 | // do other staff 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/interpreter/RequestHandlerTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.interpreter; 5 | 6 | /** 7 | * https://www.geeksforgeeks.org/intercepting-filter-pattern/ 8 | * 9 | * @author Atanu Bhowmick 10 | * 11 | */ 12 | public class RequestHandlerTest { 13 | 14 | /** 15 | * @param args 16 | */ 17 | public static void main(String[] args) { 18 | FilterManager filterManager = new FilterManager(new Target()); 19 | filterManager.setFilter(new AuthenticationFilter()); 20 | filterManager.setFilter(new DebugFilter()); 21 | 22 | RequestHandler httpRequestHandler = new RequestHandler(); 23 | httpRequestHandler.setFilterManager(filterManager); 24 | httpRequestHandler.handleRequest("Download File"); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/interpreter/Target.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.interpreter; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Target { 11 | 12 | public void execute(String request) { 13 | System.out.println("Executing : " + request); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/iterator/Collection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.iterator; 5 | 6 | /** 7 | * 8 | * @author Atanu Bhowmick 9 | * 10 | */ 11 | public interface Collection { 12 | 13 | public Iterator createIterator(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/iterator/Iterator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.iterator; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface Iterator { 11 | 12 | public boolean hasNext(); 13 | 14 | public Object getNext(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/iterator/Notification.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.iterator; 5 | 6 | import java.time.LocalDateTime; 7 | 8 | /** 9 | * @author Atanu Bhowmick 10 | * 11 | */ 12 | public class Notification { 13 | 14 | private String notificationMsg; 15 | private LocalDateTime receivingTimestamp; 16 | 17 | public Notification(String notificationMsg, LocalDateTime receivingTimestamp) { 18 | this.notificationMsg = notificationMsg; 19 | this.receivingTimestamp = receivingTimestamp; 20 | } 21 | 22 | public String getNotificationMsg() { 23 | return notificationMsg; 24 | } 25 | 26 | public LocalDateTime getReceivingTimestamp() { 27 | return receivingTimestamp; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/iterator/NotificationBar.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.iterator; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class NotificationBar { 11 | 12 | private NotificationCollection collection; 13 | 14 | public NotificationBar(NotificationCollection collection) { 15 | this.collection = collection; 16 | } 17 | 18 | public void printNotifications() { 19 | Iterator iterator = collection.createIterator(); 20 | System.out.println("-------NOTIFICATION BAR------------"); 21 | while (iterator.hasNext()) { 22 | Notification n = (Notification) iterator.getNext(); 23 | System.out.println(n.getReceivingTimestamp() + " " + n.getNotificationMsg()); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/iterator/NotificationBarTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.iterator; 5 | 6 | import java.time.LocalDateTime; 7 | 8 | /** 9 | * https://www.geeksforgeeks.org/iterator-pattern/ 10 | * 11 | * @author Atanu Bhowmick 12 | * 13 | */ 14 | public class NotificationBarTest { 15 | 16 | public static void main(String args[]) { 17 | NotificationBarTest test = new NotificationBarTest(); 18 | NotificationBar nb = new NotificationBar(test.getNotificationCollection()); 19 | nb.printNotifications(); 20 | } 21 | 22 | private NotificationCollection getNotificationCollection() { 23 | NotificationCollection nc = new NotificationCollection(); 24 | LocalDateTime now = LocalDateTime.now(); 25 | nc.addItem("Rohit has accepted you connection request", now); 26 | nc.addItem("Anupam posted a question in Java-Expert group", now.minusMinutes(15)); 27 | nc.addItem("Raju liked your post in Java-Expert group", now.minusHours(2)); 28 | nc.addItem("Java Trainer shared a post you might be interested", now.minusHours(4).minusMinutes(10)); 29 | return nc; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/iterator/NotificationCollection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.iterator; 5 | 6 | import java.time.LocalDateTime; 7 | 8 | /** 9 | * @author Atanu Bhowmick 10 | * 11 | */ 12 | public class NotificationCollection implements Collection { 13 | 14 | private static final int MAX_ITEMS = 100; 15 | 16 | private int currentPosition = 0; 17 | private Notification[] notifications; 18 | 19 | @Override 20 | public Iterator createIterator() { 21 | return new NotificationIterator(notifications); 22 | } 23 | 24 | public NotificationCollection() { 25 | notifications = new Notification[MAX_ITEMS]; 26 | } 27 | 28 | public void addItem(String message, LocalDateTime timestamp) { 29 | Notification notification = new Notification(message, timestamp); 30 | if (currentPosition >= MAX_ITEMS) { 31 | throw new ArrayIndexOutOfBoundsException(currentPosition); 32 | } else { 33 | notifications[currentPosition++] = notification; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/iterator/NotificationIterator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.iterator; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class NotificationIterator implements Iterator { 11 | 12 | private Notification[] notifications; 13 | 14 | private int currentIndex = 0; 15 | 16 | public NotificationIterator(Notification[] notifications) { 17 | this.notifications = notifications; 18 | } 19 | 20 | @Override 21 | public boolean hasNext() { 22 | if (currentIndex < notifications.length && notifications[currentIndex] != null) { 23 | return true; 24 | } 25 | return false; 26 | } 27 | 28 | @Override 29 | public Object getNext() { 30 | return notifications[currentIndex++]; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/mediator/ChatBox.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.mediator; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface ChatBox { 11 | 12 | public void sendMessage(String msg, User user); 13 | 14 | public void addUser(User user); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/mediator/ChatBoxImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.mediator; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public class ChatBoxImpl implements ChatBox { 14 | 15 | private List users; 16 | 17 | public ChatBoxImpl() { 18 | users = new ArrayList<>(); 19 | } 20 | 21 | @Override 22 | public void sendMessage(String msg, User sender) { 23 | for (User u : this.users) { 24 | // message should not be received by the user sending it 25 | if (u != sender) { 26 | u.receive(msg); 27 | } 28 | } 29 | } 30 | 31 | @Override 32 | public void addUser(User user) { 33 | this.users.add(user); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/mediator/ChatClientTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.mediator; 5 | 6 | /** 7 | * https://www.digitalocean.com/community/tutorials/mediator-design-pattern-java 8 | * 9 | * @author Atanu Bhowmick 10 | * 11 | */ 12 | public class ChatClientTest { 13 | 14 | /** 15 | * @param args 16 | */ 17 | public static void main(String[] args) { 18 | ChatBox mediator = new ChatBoxImpl(); 19 | User user1 = new UserImpl(mediator, "Pankaj"); 20 | User user2 = new UserImpl(mediator, "Lisa"); 21 | User user3 = new UserImpl(mediator, "Saurabh"); 22 | User user4 = new UserImpl(mediator, "David"); 23 | mediator.addUser(user1); 24 | mediator.addUser(user2); 25 | mediator.addUser(user3); 26 | mediator.addUser(user4); 27 | 28 | user1.send("Hi All"); 29 | user2.send("Hello. How are you?"); 30 | user3.send("Good morning!"); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/mediator/User.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.mediator; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public abstract class User { 11 | 12 | protected ChatBox chatBox; 13 | protected String name; 14 | 15 | public User(ChatBox chatBox, String name) { 16 | this.chatBox = chatBox; 17 | this.name = name; 18 | } 19 | 20 | public abstract void send(String msg); 21 | 22 | public abstract void receive(String msg); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/mediator/UserImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.mediator; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class UserImpl extends User { 11 | 12 | public UserImpl(ChatBox chatBox, String name) { 13 | super(chatBox, name); 14 | } 15 | 16 | @Override 17 | public void send(String msg) { 18 | System.out.println("[Sent] " + this.name + " : " + msg); 19 | this.chatBox.sendMessage(msg, this); 20 | } 21 | 22 | @Override 23 | public void receive(String msg) { 24 | System.out.println("[Received] " + this.name + " : " + msg); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/memento/Article.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.memento; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Article { 11 | 12 | private long id; 13 | private String title; 14 | private String content; 15 | 16 | public Article(long id, String title) { 17 | super(); 18 | this.id = id; 19 | this.title = title; 20 | } 21 | 22 | public long getId() { 23 | return id; 24 | } 25 | 26 | public void setId(long id) { 27 | this.id = id; 28 | } 29 | 30 | public String getTitle() { 31 | return title; 32 | } 33 | 34 | public void setTitle(String title) { 35 | this.title = title; 36 | } 37 | 38 | public String getContent() { 39 | return content; 40 | } 41 | 42 | public void setContent(String content) { 43 | this.content = content; 44 | } 45 | 46 | public void addContent(String content) { 47 | this.content += content; 48 | } 49 | 50 | /** 51 | * Create a memento 52 | * 53 | * @return 54 | */ 55 | public ArticleMemento createMemento() { 56 | ArticleMemento memento = new ArticleMemento(id, title, content); 57 | return memento; 58 | } 59 | 60 | /** 61 | * Restore the article from a memento 62 | * @param memento 63 | */ 64 | public void restore(ArticleMemento memento) { 65 | this.id = memento.getId(); 66 | this.title = memento.getTitle(); 67 | this.content = memento.getContent(); 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return "Article [id = " + id + ", title = " + title + ", content = " + content + "]"; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/memento/ArticleMemento.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.memento; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public final class ArticleMemento { 11 | 12 | private final long id; 13 | private final String title; 14 | private final String content; 15 | 16 | public ArticleMemento(long id, String title, String content) { 17 | super(); 18 | this.id = id; 19 | this.title = title; 20 | this.content = content; 21 | } 22 | 23 | public long getId() { 24 | return id; 25 | } 26 | 27 | public String getTitle() { 28 | return title; 29 | } 30 | 31 | public String getContent() { 32 | return content; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/memento/MementoTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.memento; 5 | 6 | /** 7 | * https://howtodoinjava.com/design-patterns/behavioral/memento-design-pattern/ 8 | * https://www.baeldung.com/java-memento-design-pattern 9 | * 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public class MementoTest { 14 | 15 | /** 16 | * @param args 17 | */ 18 | public static void main(String[] args) { 19 | Article article = new Article(1, "My Article"); 20 | article.setContent("ABCD"); // original content 21 | System.out.println("Content created"); 22 | System.out.println(article); 23 | 24 | // created immutable memento 25 | ArticleMemento memento1 = article.createMemento(); 26 | 27 | article.setContent("123"); // changed content 28 | System.out.println("Content replaced"); 29 | System.out.println(article); 30 | 31 | article.restore(memento1); // UNDO change 32 | System.out.println("Content restored"); 33 | System.out.println(article); // original content 34 | 35 | article.addContent("PQRS"); // Updated content 36 | System.out.println("Content updated"); 37 | System.out.println(article); 38 | 39 | // created immutable memento 40 | ArticleMemento memento2 = article.createMemento(); 41 | 42 | article.addContent("xyz"); // changed content 43 | System.out.println("Content updated again"); 44 | System.out.println(article); 45 | 46 | article.restore(memento2); // UNDO change 47 | System.out.println("Content restored to previous state"); 48 | System.out.println(article); // original content 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/observer/CurrentConditionsDisplay.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.observer; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class CurrentConditionsDisplay implements Observer, DisplayElement { 11 | 12 | private float temperature; 13 | private float humidity; 14 | private Subject weatherData; 15 | 16 | public CurrentConditionsDisplay(Subject weatherData) { 17 | this.weatherData = weatherData; 18 | weatherData.registerObserver(this); 19 | } 20 | 21 | @Override 22 | public void update(float temperature, float humidity, float pressure) { 23 | this.temperature = temperature; 24 | this.humidity = humidity; 25 | display(); 26 | } 27 | 28 | @Override 29 | public void display() { 30 | System.out.println("Current conditions: " + temperature 31 | + "F degrees and " + humidity + "% humidity"); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/observer/DisplayElement.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.observer; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface DisplayElement { 11 | 12 | public void display(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/observer/Observer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.observer; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface Observer { 11 | 12 | public void update(float temp, float humidity, float pressure); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/observer/ObserverPatternTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.observer; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ObserverPatternTest { 11 | 12 | /** 13 | * @param args 14 | */ 15 | public static void main(String[] args) { 16 | WeatherData weatherData = new WeatherData(); 17 | CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); 18 | /* 19 | * StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); 20 | * ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData); 21 | */ 22 | weatherData.setMeasurements(80, 65, 30.4f); 23 | weatherData.setMeasurements(82, 70, 29.2f); 24 | weatherData.setMeasurements(78, 90, 29.2f); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/observer/Subject.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.observer; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface Subject { 11 | 12 | public void registerObserver(Observer o); 13 | 14 | public void removeObserver(Observer o); 15 | 16 | public void notifyObservers(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/observer/WeatherData.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.observer; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public class WeatherData implements Subject { 14 | 15 | private List observers; 16 | private float temperature; 17 | private float humidity; 18 | private float pressure; 19 | 20 | public WeatherData() { 21 | observers = new ArrayList<>(); 22 | } 23 | 24 | @Override 25 | public void registerObserver(Observer o) { 26 | observers.add(o); 27 | } 28 | 29 | @Override 30 | public void removeObserver(Observer o) { 31 | int i = observers.indexOf(o); 32 | if (i >= 0) { 33 | observers.remove(i); 34 | } 35 | } 36 | 37 | @Override 38 | public void notifyObservers() { 39 | for (int i = 0; i < observers.size(); i++) { 40 | Observer observer = observers.get(i); 41 | observer.update(temperature, humidity, pressure); 42 | } 43 | } 44 | 45 | public void measurementsChanged() { 46 | notifyObservers(); 47 | } 48 | 49 | public void setMeasurements(float temperature, float humidity, float pressure) { 50 | this.temperature = temperature; 51 | this.humidity = humidity; 52 | this.pressure = pressure; 53 | measurementsChanged(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/state/DeliveredState.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.state; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class DeliveredState implements State { 11 | 12 | @Override 13 | public void next(Package pkg) { 14 | System.out.println("This package is already delivered."); 15 | } 16 | 17 | @Override 18 | public void prev(Package pkg) { 19 | pkg.setState(new DeliveryState()); 20 | } 21 | 22 | @Override 23 | public void printStatus() { 24 | System.out.println("Package is delivered to the customer."); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/state/DeliveryState.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.state; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class DeliveryState implements State { 11 | 12 | @Override 13 | public void next(Package pkg) { 14 | pkg.setState(new DeliveredState()); 15 | } 16 | 17 | @Override 18 | public void prev(Package pkg) { 19 | pkg.setState(new ShippingState()); 20 | } 21 | 22 | @Override 23 | public void printStatus() { 24 | System.out.println("Out for delivery."); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/state/OrderedState.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.state; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class OrderedState implements State { 11 | 12 | @Override 13 | public void next(Package pkg) { 14 | pkg.setState(new ShippingState()); 15 | } 16 | 17 | @Override 18 | public void prev(Package pkg) { 19 | System.out.println("This is the initial state."); 20 | } 21 | 22 | @Override 23 | public void printStatus() { 24 | System.out.println("Order has been placed successfully. The package would be shipped to the currier shortly."); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/state/Package.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.state; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Package { 11 | 12 | private State state = new OrderedState(); 13 | 14 | public void previousState() { 15 | state.prev(this); 16 | } 17 | 18 | public void nextState() { 19 | state.next(this); 20 | } 21 | 22 | public void printStatus() { 23 | state.printStatus(); 24 | } 25 | 26 | public State getState() { 27 | return state; 28 | } 29 | 30 | public void setState(State state) { 31 | this.state = state; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/state/ShippingState.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.state; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ShippingState implements State { 11 | 12 | @Override 13 | public void next(Package pkg) { 14 | pkg.setState(new DeliveryState()); 15 | } 16 | 17 | @Override 18 | public void prev(Package pkg) { 19 | pkg.setState(new OrderedState()); 20 | } 21 | 22 | @Override 23 | public void printStatus() { 24 | System.out.println("Package is shippedn to the currier. Currently in transition."); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/state/State.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.state; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface State { 11 | 12 | public void next(Package pkg); 13 | 14 | public void prev(Package pkg); 15 | 16 | public void printStatus(); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/state/StatePatternTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.state; 5 | 6 | /** 7 | * https://www.baeldung.com/java-state-design-pattern 8 | * https://www.digitalocean.com/community/tutorials/state-design-pattern-java 9 | * 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public class StatePatternTest { 14 | 15 | /** 16 | * @param args 17 | */ 18 | public static void main(String[] args) { 19 | Package pkg = new Package(); 20 | pkg.printStatus(); 21 | 22 | pkg.nextState(); 23 | pkg.printStatus(); 24 | 25 | pkg.nextState(); 26 | pkg.printStatus(); 27 | 28 | pkg.nextState(); 29 | pkg.printStatus(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/strategy/CreditCard.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.strategy; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class CreditCard { 11 | 12 | private String name; 13 | private String cardNumber; 14 | private String cvv; 15 | private String dateOfExpiry; 16 | 17 | public CreditCard(String name, String cardNumber, String cvv, String dateOfExpiry) { 18 | this.name = name; 19 | this.cardNumber = cardNumber; 20 | this.cvv = cvv; 21 | this.dateOfExpiry = dateOfExpiry; 22 | } 23 | 24 | public String getName() { 25 | return name; 26 | } 27 | 28 | public String getCardNumber() { 29 | return cardNumber; 30 | } 31 | 32 | public String getCvv() { 33 | return cvv; 34 | } 35 | 36 | public String getDateOfExpiry() { 37 | return dateOfExpiry; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/strategy/CreditCardPayStrategy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.strategy; 5 | 6 | /** 7 | * 8 | * @author Atanu Bhowmick 9 | */ 10 | public class CreditCardPayStrategy implements PaymentStrategy { 11 | 12 | private CreditCard creditCard; 13 | 14 | public CreditCardPayStrategy(CreditCard creditCard) { 15 | this.creditCard = creditCard; 16 | } 17 | 18 | @Override 19 | public void pay(double amount) { 20 | System.out.println("Paying " + amount + " through credit card ending " 21 | + creditCard.getCardNumber().substring(12)); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/strategy/Item.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.strategy; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Item { 11 | 12 | private String itemCode; 13 | private String itemName; 14 | private double price; 15 | 16 | public Item() { 17 | // Default Constructor 18 | } 19 | 20 | public Item(String itemCode, String itemName, double price) { 21 | this.itemCode = itemCode; 22 | this.itemName = itemName; 23 | this.price = price; 24 | } 25 | 26 | public String getItemCode() { 27 | return itemCode; 28 | } 29 | 30 | public void setItemCode(String itemCode) { 31 | this.itemCode = itemCode; 32 | } 33 | 34 | public String getItemName() { 35 | return itemName; 36 | } 37 | 38 | public void setItemName(String itemName) { 39 | this.itemName = itemName; 40 | } 41 | 42 | public double getPrice() { 43 | return price; 44 | } 45 | 46 | public void setPrice(double price) { 47 | this.price = price; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/strategy/NetBankingDetails.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.strategy; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class NetBankingDetails { 11 | 12 | private String bankName; 13 | private String userId; 14 | private char[] password; 15 | 16 | public NetBankingDetails(String bankName, String userId, char[] password) { 17 | this.bankName = bankName; 18 | this.userId = userId; 19 | this.password = password; 20 | } 21 | 22 | public String getBankName() { 23 | return bankName; 24 | } 25 | 26 | public String getUserId() { 27 | return userId; 28 | } 29 | 30 | public char[] getPassword() { 31 | return password; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/strategy/NetBankingPayStrategy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.strategy; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class NetBankingPayStrategy implements PaymentStrategy { 11 | 12 | private NetBankingDetails netBankingDetails; 13 | 14 | public NetBankingPayStrategy(NetBankingDetails netBankingDetails) { 15 | this.netBankingDetails = netBankingDetails; 16 | } 17 | 18 | @Override 19 | public void pay(double amount) { 20 | System.out.println("Paying " + amount + " with netbanking from " 21 | + netBankingDetails.getBankName() 22 | + " Customer Id: " + netBankingDetails.getUserId()); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/strategy/PaymentStrategy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.strategy; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface PaymentStrategy { 11 | 12 | public void pay(double amount); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/strategy/ShoppingCart.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.strategy; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public class ShoppingCart { 14 | 15 | private List items; 16 | 17 | public ShoppingCart() { 18 | this.items = new ArrayList(); 19 | } 20 | 21 | public void addItem(Item item) { 22 | this.items.add(item); 23 | } 24 | 25 | public void removeItem(Item item) { 26 | this.items.remove(item); 27 | } 28 | 29 | public void pay(PaymentStrategy paymentMethod) { 30 | double amount = calculateTotal(); 31 | paymentMethod.pay(amount); 32 | } 33 | 34 | private double calculateTotal() { 35 | double sum = 0; 36 | for (Item item : items) { 37 | sum += item.getPrice(); 38 | } 39 | return sum; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/strategy/ShoppingCartTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.strategy; 5 | 6 | /** 7 | * https://www.digitalocean.com/community/tutorials/strategy-design-pattern-in-java-example-tutorial 8 | * https://refactoring.guru/design-patterns/strategy/java/example#example-0 9 | * 10 | * @author Atanu Bhowmick 11 | */ 12 | public class ShoppingCartTest { 13 | 14 | public static void main(String[] args) { 15 | ShoppingCart cart = new ShoppingCart(); 16 | 17 | Item item1 = new Item("1001", "HP Pendrive", 1200.00); 18 | Item item2 = new Item("1002", "Head First Java Book", 700.00); 19 | 20 | cart.addItem(item1); 21 | cart.addItem(item2); 22 | 23 | // pay by credit card 24 | CreditCard creditCard = new CreditCard("Abc Xyz", "1234567890123456", "123", "12/2030"); 25 | cart.pay(new CreditCardPayStrategy(creditCard)); 26 | 27 | // pay by credit card 28 | cart.pay(new UpiPayStrategy(new UpiDetails("xyz@ibl", "1234".toCharArray(), "9999999999"))); 29 | 30 | // pay by credit card 31 | cart.pay(new NetBankingPayStrategy(new NetBankingDetails("HDFC Bank", "12345", "12345".toCharArray()))); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/strategy/UpiDetails.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.strategy; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class UpiDetails { 11 | 12 | private String upiId; 13 | private char[] upiPin; 14 | private String mobileNum; 15 | 16 | public UpiDetails(String upiId, char[] upiPin, String mobileNum) { 17 | this.upiId = upiId; 18 | this.upiPin = upiPin; 19 | this.mobileNum = mobileNum; 20 | } 21 | 22 | public String getUpiId() { 23 | return upiId; 24 | } 25 | 26 | public char[] getUpiPin() { 27 | return upiPin; 28 | } 29 | 30 | public String getMobileNum() { 31 | return mobileNum; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/strategy/UpiPayStrategy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.strategy; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class UpiPayStrategy implements PaymentStrategy { 11 | 12 | private UpiDetails upiDetails; 13 | 14 | public UpiPayStrategy(UpiDetails upiDetails) { 15 | this.upiDetails = upiDetails; 16 | } 17 | 18 | @Override 19 | public void pay(double amount) { 20 | System.out.println("Paying " + amount + " using UPI from " + upiDetails.getUpiId()); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/template/method/GlassHouse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.template.method; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class GlassHouse extends HouseTemplate { 11 | 12 | @Override 13 | public void buildPillars() { 14 | System.out.println("Build pillers with woods"); 15 | } 16 | 17 | @Override 18 | public void buildWalls() { 19 | System.out.println("Building Wooden Walls"); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/template/method/HouseTemplate.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.template.method; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public abstract class HouseTemplate { 11 | 12 | public final void buildHouse() { 13 | buildFoundation(); 14 | buildPillars(); 15 | buildWalls(); 16 | buildWindows(); 17 | System.out.println("House is built"); 18 | } 19 | 20 | // methods to be implemented by subclasses 21 | public abstract void buildPillars(); 22 | public abstract void buildWalls(); 23 | 24 | private void buildFoundation() { 25 | System.out.println("Building foundation with cement, iron rods and sand"); 26 | } 27 | 28 | // default implementation 29 | private void buildWindows() { 30 | System.out.println("Building Glass Windows"); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/template/method/TemplateMethodPatternTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.template.method; 5 | 6 | /** 7 | * https://www.digitalocean.com/community/tutorials/template-method-design-pattern-in-java 8 | * 9 | * @author Atanu Bhowmick 10 | * 11 | */ 12 | public class TemplateMethodPatternTest { 13 | 14 | /** 15 | * @param args 16 | */ 17 | public static void main(String[] args) { 18 | HouseTemplate houseType = new WoodenHouse(); 19 | houseType.buildHouse(); 20 | 21 | System.out.println("************"); 22 | 23 | houseType = new GlassHouse(); 24 | houseType.buildHouse(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/template/method/WoodenHouse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.template.method; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class WoodenHouse extends HouseTemplate { 11 | 12 | @Override 13 | public void buildPillars() { 14 | System.out.println("Building Pillars with glass coating"); 15 | } 16 | 17 | @Override 18 | public void buildWalls() { 19 | System.out.println("Building Glass Walls"); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/visitor/Element.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.visitor; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface Element { 11 | 12 | public void accept(Visitor visitor); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/visitor/ElementVisitor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.visitor; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ElementVisitor implements Visitor { 11 | 12 | @Override 13 | public void visit(XmlElement xe) { 14 | System.out.println("Visiting XML Element"); 15 | System.out.println(xe.getValue()); 16 | 17 | // Visit child 18 | visitChild(xe); 19 | 20 | // Visit next element 21 | XmlElement next = xe.getNext(); 22 | while (next != null) { 23 | System.out.println(next.getValue()); 24 | visitChild(xe.getChild()); 25 | next = next.getNext(); 26 | } 27 | } 28 | 29 | @Override 30 | public void visit(JsonElement je) { 31 | System.out.println("Visiting JSON Element"); 32 | 33 | System.out.println(je.getValue()); 34 | 35 | // Visit child 36 | visitChild(je); 37 | 38 | // Visit next element 39 | JsonElement next = je.getNext(); 40 | while (next != null) { 41 | System.out.println(next.getValue()); 42 | visitChild(je.getChild()); 43 | next = next.getNext(); 44 | } 45 | } 46 | 47 | @Override 48 | public void visit(YmlElement ye) { 49 | System.out.println("Visiting YML Element"); 50 | 51 | System.out.println(ye.getValue()); 52 | 53 | // Visit child 54 | visitChild(ye); 55 | 56 | // Visit next element 57 | YmlElement next = ye.getNext(); 58 | while (next != null) { 59 | System.out.println(next.getValue()); 60 | visitChild(ye.getChild()); 61 | next = next.getNext(); 62 | } 63 | } 64 | 65 | private void visitChild(XmlElement xe) { 66 | XmlElement child = xe.getChild(); 67 | while (child != null) { 68 | System.out.println(child.getValue()); 69 | child = child.getNext(); 70 | } 71 | } 72 | 73 | private void visitChild(JsonElement je) { 74 | JsonElement child = je.getChild(); 75 | while (child != null) { 76 | System.out.println(child.getValue()); 77 | child = child.getNext(); 78 | } 79 | } 80 | 81 | private void visitChild(YmlElement ye) { 82 | YmlElement child = ye.getChild(); 83 | while (child != null) { 84 | System.out.println(child.getValue()); 85 | child = child.getNext(); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/visitor/JsonElement.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.visitor; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class JsonElement implements Element { 11 | 12 | private String value; 13 | private JsonElement child; 14 | private JsonElement next; 15 | 16 | public JsonElement(String value) { 17 | this.value = value; 18 | } 19 | 20 | public JsonElement(String value, JsonElement child, JsonElement next) { 21 | this.value = value; 22 | this.child = child; 23 | this.next = next; 24 | } 25 | 26 | public String getValue() { 27 | return value; 28 | } 29 | 30 | public void setValue(String value) { 31 | this.value = value; 32 | } 33 | 34 | public JsonElement getChild() { 35 | return child; 36 | } 37 | 38 | public void setChild(JsonElement child) { 39 | this.child = child; 40 | } 41 | 42 | public JsonElement getNext() { 43 | return next; 44 | } 45 | 46 | public void setNext(JsonElement next) { 47 | this.next = next; 48 | } 49 | 50 | @Override 51 | public void accept(Visitor visitor) { 52 | visitor.visit(this); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/visitor/Visitor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.visitor; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface Visitor { 11 | 12 | public void visit(XmlElement xe); 13 | 14 | public void visit(JsonElement je); 15 | 16 | public void visit(YmlElement ye); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/visitor/VisitorTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.visitor; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * https://www.baeldung.com/java-visitor-pattern 11 | * https://www.javatpoint.com/visitor-design-pattern-java 12 | * 13 | * @author Atanu Bhowmick 14 | * 15 | */ 16 | public class VisitorTest { 17 | 18 | /** 19 | * @param args 20 | */ 21 | public static void main(String[] args) { 22 | List list = new ArrayList<>(); 23 | list.add(new XmlElement("5", new XmlElement("10"), new XmlElement("25"))); 24 | list.add(new JsonElement("rootJson", new JsonElement("17"), new JsonElement("24"))); 25 | list.add(new YmlElement("yml 100")); 26 | 27 | Visitor visitor = new ElementVisitor(); 28 | visit(list, visitor); 29 | } 30 | 31 | private static void visit(List elements, Visitor visitor) { 32 | 33 | for(Element element: elements) { 34 | element.accept(visitor); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/visitor/XmlElement.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.visitor; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class XmlElement implements Element { 11 | 12 | private String value; 13 | private XmlElement child; 14 | private XmlElement next; 15 | 16 | public XmlElement(String value) { 17 | this.value = value; 18 | } 19 | 20 | public XmlElement(String value, XmlElement child, XmlElement next) { 21 | this.value = value; 22 | this.child = child; 23 | this.next = next; 24 | } 25 | 26 | public String getValue() { 27 | return value; 28 | } 29 | 30 | public void setValue(String value) { 31 | this.value = value; 32 | } 33 | 34 | public XmlElement getChild() { 35 | return child; 36 | } 37 | 38 | public void setChild(XmlElement child) { 39 | this.child = child; 40 | } 41 | 42 | public XmlElement getNext() { 43 | return next; 44 | } 45 | 46 | public void setNext(XmlElement next) { 47 | this.next = next; 48 | } 49 | 50 | @Override 51 | public void accept(Visitor visitor) { 52 | visitor.visit(this); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/behavioral/visitor/YmlElement.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.behavioral.visitor; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class YmlElement implements Element { 11 | 12 | private String value; 13 | private YmlElement child; 14 | private YmlElement next; 15 | 16 | public YmlElement(String value) { 17 | this.value = value; 18 | } 19 | 20 | public YmlElement(String value, YmlElement child, YmlElement next) { 21 | this.value = value; 22 | this.child = child; 23 | this.next = next; 24 | } 25 | 26 | public String getValue() { 27 | return value; 28 | } 29 | 30 | public void setValue(String value) { 31 | this.value = value; 32 | } 33 | 34 | public YmlElement getChild() { 35 | return child; 36 | } 37 | 38 | public void setChild(YmlElement child) { 39 | this.child = child; 40 | } 41 | 42 | public YmlElement getNext() { 43 | return next; 44 | } 45 | 46 | public void setNext(YmlElement next) { 47 | this.next = next; 48 | } 49 | 50 | @Override 51 | public void accept(Visitor visitor) { 52 | visitor.visit(this); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/builder/Computer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.builder; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Computer { 11 | 12 | private ComputerProcessor processor; 13 | private ComputerRAM ram; 14 | private String hddType; 15 | private String hddSize; 16 | private int displaySize; 17 | 18 | private Computer(ComputerBuilder builder) { 19 | this.processor = builder.processor; 20 | this.ram = builder.ram; 21 | this.hddType = builder.hddType; 22 | this.hddSize = builder.hddSize; 23 | this.displaySize = builder.displaySize; 24 | } 25 | 26 | public static ComputerBuilder builder() { 27 | return new ComputerBuilder(); 28 | } 29 | 30 | /** 31 | * @return the processor 32 | */ 33 | public ComputerProcessor getProcessor() { 34 | return processor; 35 | } 36 | 37 | /** 38 | * @return the ram 39 | */ 40 | public ComputerRAM getRam() { 41 | return ram; 42 | } 43 | 44 | /** 45 | * @return the hddType 46 | */ 47 | public String getHddType() { 48 | return hddType; 49 | } 50 | 51 | /** 52 | * @return the hddSize 53 | */ 54 | public String getHddSize() { 55 | return hddSize; 56 | } 57 | 58 | /** 59 | * @return the displaySize 60 | */ 61 | public int getDisplaySize() { 62 | return displaySize; 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | return "[" 68 | + "processor: " + processor 69 | + ", RAM: " + ram 70 | + ", hddType:" + hddType 71 | + ", hddSize: " + hddSize 72 | + ", displaySize: " + displaySize 73 | + "]"; 74 | } 75 | 76 | public static class ComputerBuilder { 77 | 78 | private ComputerProcessor processor; 79 | private ComputerRAM ram; 80 | private String hddType; 81 | private String hddSize; 82 | private int displaySize; 83 | 84 | /** 85 | * @param processor the processor to set 86 | * @return 87 | */ 88 | public ComputerBuilder setProcessor(ComputerProcessor processor) { 89 | this.processor = processor; 90 | return this; 91 | } 92 | 93 | /** 94 | * @param ram the ram to set 95 | */ 96 | public ComputerBuilder setRam(ComputerRAM ram) { 97 | this.ram = ram; 98 | return this; 99 | } 100 | 101 | /** 102 | * @param hddType the hddType to set 103 | */ 104 | public ComputerBuilder setHddType(String hddType) { 105 | this.hddType = hddType; 106 | return this; 107 | } 108 | 109 | /** 110 | * @param hddSize the hddSize to set 111 | */ 112 | public ComputerBuilder setHddSize(String hddSize) { 113 | this.hddSize = hddSize; 114 | return this; 115 | } 116 | 117 | /** 118 | * @param displaySize the displaySize to set 119 | */ 120 | public ComputerBuilder setDisplaySize(int displaySize) { 121 | this.displaySize = displaySize; 122 | return this; 123 | } 124 | 125 | public Computer build() { 126 | return new Computer(this); 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/builder/ComputerBuilderTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.builder; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ComputerBuilderTest { 11 | 12 | public static void main(String[] args) { 13 | Computer computer = Computer.builder() 14 | .setProcessor(ComputerProcessor.builder() 15 | .setManufacturer("Intel") 16 | .setName("Code i7") 17 | .setOperatingFrequency("2 GHZ") 18 | .setMaximumFrequency("4.5 GHz") 19 | .setPowerConsumption("32 Watt") 20 | .build()) 21 | .setHddType("SSD") 22 | .setHddSize("1 TB") 23 | .setRam(ComputerRAM.builder() 24 | .setManufacturer("Samsung") 25 | .setName("Samsung M1") 26 | .setSize("16 GB") 27 | .setType("DDR4") 28 | .build()) 29 | .setDisplaySize(14) 30 | .build(); 31 | 32 | System.out.println(computer); 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/builder/ComputerProcessor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.builder; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ComputerProcessor { 11 | 12 | private String manufacturer; 13 | private String name; 14 | private String operatingFrequency; 15 | private String maximumFrequency; 16 | private String powerConsumption; 17 | 18 | private ComputerProcessor(ProcessorBuilder builder) { 19 | this.manufacturer = builder.manufacturer; 20 | this.name = builder.name; 21 | this.operatingFrequency = builder.operatingFrequency; 22 | this.maximumFrequency = builder.maximumFrequency; 23 | this.powerConsumption = builder.powerConsumption; 24 | } 25 | 26 | public static ProcessorBuilder builder() { 27 | return new ProcessorBuilder(); 28 | } 29 | 30 | /** 31 | * @return the manufacturer 32 | */ 33 | public String getManufacturer() { 34 | return manufacturer; 35 | } 36 | 37 | /** 38 | * @return the name 39 | */ 40 | public String getName() { 41 | return name; 42 | } 43 | 44 | /** 45 | * @return the operatingFrequency 46 | */ 47 | public String getOperatingFrequency() { 48 | return operatingFrequency; 49 | } 50 | 51 | /** 52 | * @return the maximumFrequency 53 | */ 54 | public String getMaximumFrequency() { 55 | return maximumFrequency; 56 | } 57 | 58 | /** 59 | * @return the powerConsumption 60 | */ 61 | public String getPowerConsumption() { 62 | return powerConsumption; 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | return "[" 68 | + "manufacturer: " + manufacturer 69 | + ", name: " + name 70 | + ", operatingFrequency:" + operatingFrequency 71 | + ", maximumFrequency: " + maximumFrequency 72 | + ", powerConsumption: " + powerConsumption 73 | + "]"; 74 | } 75 | 76 | public static class ProcessorBuilder { 77 | 78 | private String manufacturer; 79 | private String name; 80 | private String operatingFrequency; 81 | private String maximumFrequency; 82 | private String powerConsumption; 83 | 84 | /** 85 | * @param manufacturer the manufacturer to set 86 | */ 87 | public ProcessorBuilder setManufacturer(String manufacturer) { 88 | this.manufacturer = manufacturer; 89 | return this; 90 | } 91 | 92 | /** 93 | * @param name the name to set 94 | */ 95 | public ProcessorBuilder setName(String name) { 96 | this.name = name; 97 | return this; 98 | } 99 | 100 | /** 101 | * @param operatingFrequency the operatingFrequency to set 102 | */ 103 | public ProcessorBuilder setOperatingFrequency(String operatingFrequency) { 104 | this.operatingFrequency = operatingFrequency; 105 | return this; 106 | } 107 | 108 | /** 109 | * @param maximumFrequency the maximumFrequency to set 110 | */ 111 | public ProcessorBuilder setMaximumFrequency(String maximumFrequency) { 112 | this.maximumFrequency = maximumFrequency; 113 | return this; 114 | } 115 | 116 | /** 117 | * @param powerConsumption the powerConsumption to set 118 | */ 119 | public ProcessorBuilder setPowerConsumption(String powerConsumption) { 120 | this.powerConsumption = powerConsumption; 121 | return this; 122 | } 123 | 124 | public ComputerProcessor build() { 125 | return new ComputerProcessor(this); 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/builder/ComputerRAM.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.builder; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ComputerRAM { 11 | 12 | private String manufacturer; 13 | private String name; 14 | private String size; 15 | private String type; 16 | 17 | private ComputerRAM(RAMBuilder builder) { 18 | this.manufacturer = builder.manufacturer; 19 | this.name = builder.name; 20 | this.size = builder.size; 21 | this.type = builder.type; 22 | } 23 | 24 | public static RAMBuilder builder() { 25 | return new RAMBuilder(); 26 | } 27 | 28 | /** 29 | * @return the manufacturer 30 | */ 31 | public String getManufacturer() { 32 | return manufacturer; 33 | } 34 | 35 | /** 36 | * @return the name 37 | */ 38 | public String getName() { 39 | return name; 40 | } 41 | 42 | /** 43 | * @return the size 44 | */ 45 | public String getSize() { 46 | return size; 47 | } 48 | 49 | /** 50 | * @return the type 51 | */ 52 | public String getType() { 53 | return type; 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | return "[" 59 | + "manufacturer: " + manufacturer 60 | + ", name: " + name 61 | + ", size:" + size 62 | + ", type: " + type 63 | + "]"; 64 | } 65 | 66 | public static class RAMBuilder { 67 | 68 | private String manufacturer; 69 | private String name; 70 | private String size; 71 | private String type; 72 | 73 | /** 74 | * @param manufacturer the manufacturer to set 75 | */ 76 | public RAMBuilder setManufacturer(String manufacturer) { 77 | this.manufacturer = manufacturer; 78 | return this; 79 | } 80 | 81 | /** 82 | * @param name the name to set 83 | */ 84 | public RAMBuilder setName(String name) { 85 | this.name = name; 86 | return this; 87 | } 88 | 89 | /** 90 | * @param size the size to set 91 | */ 92 | public RAMBuilder setSize(String size) { 93 | this.size = size; 94 | return this; 95 | } 96 | 97 | /** 98 | * @param type the type to set 99 | */ 100 | public RAMBuilder setType(String type) { 101 | this.type = type; 102 | return this; 103 | } 104 | 105 | public ComputerRAM build() { 106 | return new ComputerRAM(this); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/asbtract/AbstractFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.asbtract; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface AbstractFactory { 11 | 12 | Mobile getMobile(String mobileModel); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/asbtract/AbstractFactoryTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.asbtract; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class AbstractFactoryTest { 11 | 12 | /** 13 | * @param args 14 | */ 15 | public static void main(String[] args) { 16 | AbstractFactory androidFactory = FactoryProvider.getFactory("Android"); 17 | Mobile motorola = androidFactory.getMobile("Motorola"); 18 | motorola.brandName(); 19 | motorola.price(); 20 | 21 | Mobile samsang = androidFactory.getMobile("Samsung"); 22 | samsang.brandName(); 23 | samsang.price(); 24 | 25 | AbstractFactory iphoneFactory = FactoryProvider.getFactory("IPhone"); 26 | Mobile iphone14 = iphoneFactory.getMobile("14"); 27 | iphone14.brandName(); 28 | iphone14.price(); 29 | 30 | Mobile iphone15 = iphoneFactory.getMobile("15"); 31 | iphone15.brandName(); 32 | iphone15.price(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/asbtract/AndroidMobileFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.asbtract; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class AndroidMobileFactory implements AbstractFactory { 11 | 12 | @Override 13 | public Mobile getMobile(String mobileModel) { 14 | Mobile mobile = null; 15 | if (mobileModel.equalsIgnoreCase("Motorola")) { 16 | mobile = new MotorolaMobile(); 17 | } else if (mobileModel.equalsIgnoreCase("Samsung")) { 18 | mobile = new SamsungMobile(); 19 | } else if (mobileModel.equalsIgnoreCase("Lava")) { 20 | mobile = new RealmeMobile(); 21 | } 22 | return mobile; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/asbtract/FactoryProvider.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.asbtract; 5 | 6 | /** 7 | * The Factory Method creates objects through inheritance where the 8 | * Abstract Factory creates objects through composition. 9 | * 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public class FactoryProvider { 14 | 15 | public static AbstractFactory getFactory(String type) { 16 | if (type.equalsIgnoreCase("Android")) { 17 | return new AndroidMobileFactory(); 18 | } else if (type.equalsIgnoreCase("IPhone")) { 19 | return new IPhoneMobileFactory(); 20 | } 21 | return null; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/asbtract/IPhone14.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.asbtract; 5 | 6 | /** 7 | * @author ATANU 8 | * 9 | */ 10 | public class IPhone14 implements Mobile{ 11 | 12 | @Override 13 | public void brandName() { 14 | System.out.println("IPhone v-14"); 15 | } 16 | 17 | @Override 18 | public void price() { 19 | System.out.println("Price: 50000 INR"); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/asbtract/IPhone15.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.asbtract; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class IPhone15 implements Mobile{ 11 | 12 | @Override 13 | public void brandName() { 14 | System.out.println("IPhone v-15"); 15 | } 16 | 17 | @Override 18 | public void price() { 19 | System.out.println("Price: 100000 INR"); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/asbtract/IPhoneMobileFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.asbtract; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class IPhoneMobileFactory implements AbstractFactory { 11 | 12 | @Override 13 | public Mobile getMobile(String mobileModel) { 14 | Mobile mobile = null; 15 | if (mobileModel.equalsIgnoreCase("14")) { 16 | mobile = new IPhone14(); 17 | } else if (mobileModel.equalsIgnoreCase("15")) { 18 | mobile = new IPhone15(); 19 | } 20 | return mobile; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/asbtract/Mobile.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.asbtract; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface Mobile { 11 | 12 | public void brandName(); 13 | 14 | public void price(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/asbtract/MotorolaMobile.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.asbtract; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class MotorolaMobile implements Mobile { 11 | 12 | @Override 13 | public void brandName() { 14 | System.out.println("Motorola Mobile"); 15 | } 16 | 17 | @Override 18 | public void price() { 19 | System.out.println("Price : 25000 INR"); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/asbtract/RealmeMobile.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.asbtract; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class RealmeMobile implements Mobile { 11 | 12 | @Override 13 | public void brandName() { 14 | System.out.println("Realme Mobile"); 15 | } 16 | 17 | @Override 18 | public void price() { 19 | System.out.println("Price : 15000 INR"); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/asbtract/SamsungMobile.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.asbtract; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class SamsungMobile implements Mobile { 11 | 12 | @Override 13 | public void brandName() { 14 | System.out.println("Samsung Mobile"); 15 | } 16 | 17 | @Override 18 | public void price() { 19 | System.out.println("Price : 20000 INR"); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/method/ChicagoPizzaStore.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.method; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ChicagoPizzaStore extends PizzaStore { 11 | 12 | protected Pizza createPizza(String item) { 13 | Pizza pizza = null; 14 | if (item.equals("chicken")) { 15 | pizza = new ChicagoStyleChickenPizza(); 16 | } else if (item.equals("veggie")) { 17 | pizza = new ChicagoStyleVeggiePizza(); 18 | } 19 | return pizza; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/method/ChicagoStyleChickenPizza.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.method; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ChicagoStyleChickenPizza extends Pizza { 11 | 12 | public ChicagoStyleChickenPizza() { 13 | this.name = "Chicago Style Deep Dish Chicken Pizza"; 14 | this.dough = "Extra Thick Crust Dough"; 15 | this.sauce = "Plum Tomato Sauce"; 16 | this.toppings.add("Shredded Mozzarella Cheese"); 17 | } 18 | 19 | @Override 20 | public void cut() { 21 | System.out.println("Cutting the pizza into square slices"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/method/ChicagoStyleVeggiePizza.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.method; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ChicagoStyleVeggiePizza extends Pizza { 11 | 12 | public ChicagoStyleVeggiePizza() { 13 | this.name = "Chicago Style Veggie Pizza"; 14 | this.dough = "Thick Crust Dough"; 15 | this.sauce = "Plum Tomato Sauce"; 16 | this.toppings.add("Shredded Mozzarella Cheese"); 17 | } 18 | 19 | @Override 20 | public void cut() { 21 | System.out.println("Cutting the pizza into square slices"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/method/FactoryMethodTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.method; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class FactoryMethodTest { 11 | 12 | /** 13 | * @param args 14 | */ 15 | public static void main(String[] args) { 16 | PizzaStore nyStore = new NYPizzaStore(); 17 | PizzaStore chicagoStore = new ChicagoPizzaStore(); 18 | Pizza pizza = nyStore.orderPizza("chicken"); 19 | System.out.println("Ethan ordered a " + pizza.getName() + "\n"); 20 | pizza = chicagoStore.orderPizza("veggie"); 21 | System.out.println("Joel ordered a " + pizza.getName() + "\n"); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/method/NYPizzaStore.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.method; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class NYPizzaStore extends PizzaStore { 11 | 12 | protected Pizza createPizza(String item) { 13 | Pizza pizza = null; 14 | if (item.equals("chicken")) { 15 | pizza = new NYStyleChickenPizza(); 16 | } else if (item.equals("veggie")) { 17 | pizza = new NYStyleVeggiePizza(); 18 | } 19 | return pizza; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/method/NYStyleChickenPizza.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.method; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class NYStyleChickenPizza extends Pizza { 11 | 12 | public NYStyleChickenPizza() { 13 | this.name = "NY Style Sauce and Chicken Pizza"; 14 | this.dough = "Thin Crust Dough"; 15 | this.sauce = "Marinara Sauce"; 16 | this.toppings.add("Grated Reggiano Cheese"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/method/NYStyleVeggiePizza.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.method; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class NYStyleVeggiePizza extends Pizza { 11 | 12 | public NYStyleVeggiePizza() { 13 | this.name = "NY Style Veggie Pizza"; 14 | this.dough = "Thin Crust Dough"; 15 | this.sauce = "Marinara Sauce"; 16 | this.toppings.add("Grated Reggiano Cheese"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/method/Pizza.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.method; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public abstract class Pizza { 14 | 15 | String name; 16 | String dough; 17 | String sauce; 18 | List toppings = new ArrayList<>(); 19 | 20 | public void prepare() { 21 | System.out.println("Preparing " + name); 22 | System.out.println("Tossing dough..."); 23 | System.out.println("Adding sauce..."); 24 | System.out.println("Adding toppings:"); 25 | for (int i = 0; i < toppings.size(); i++) { 26 | System.out.println(toppings.get(i)); 27 | } 28 | } 29 | 30 | public void bake() { 31 | System.out.println("Bake for 25 minutes at 350"); 32 | } 33 | 34 | public void cut() { 35 | System.out.println("Cutting the pizza into diagonal slices"); 36 | } 37 | 38 | public void box() { 39 | System.out.println("Place pizza in official PizzaStore box"); 40 | } 41 | 42 | public String getName() { 43 | return name; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/factory/method/PizzaStore.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.factory.method; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public abstract class PizzaStore { 11 | 12 | public Pizza orderPizza(String type) { 13 | Pizza pizza = createPizza(type); 14 | pizza.prepare(); 15 | pizza.bake(); 16 | pizza.cut(); 17 | pizza.box(); 18 | return pizza; 19 | } 20 | 21 | protected abstract Pizza createPizza(String type); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/prototype/Prototype.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.prototype; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface Prototype { 11 | 12 | public Prototype getClone(); 13 | 14 | public String display(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/prototype/PrototypeTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.prototype; 5 | 6 | /** 7 | * https://www.javatpoint.com/prototype-design-pattern 8 | * 9 | * @author Atanu Bhowmick 10 | * 11 | */ 12 | public class PrototypeTest { 13 | 14 | public static void main(String[] args) { 15 | StudentRecord student = new StudentRecord(); 16 | student.setId(2501); 17 | student.setRollNo(20); 18 | student.setName("Sumon Roy"); 19 | 20 | StudentAddress address = new StudentAddress(); 21 | address.setHouseNum("N100"); 22 | address.setLocality("Sukanta Nagar, Salt Lake"); 23 | address.setCity("Kolkata"); 24 | address.setState("West bengal"); 25 | address.setPinCode(700098); 26 | 27 | student.setAddress(address); 28 | 29 | System.out.println(student.display()); 30 | 31 | StudentRecord clonedStudent = student.getClone(); 32 | System.out.println(clonedStudent.display()); 33 | 34 | System.out.println("Is same object: " + (student == clonedStudent)); 35 | System.out.println(student); 36 | System.out.println(clonedStudent); 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/prototype/StudentAddress.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.prototype; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class StudentAddress implements Prototype { 11 | 12 | private String houseNum; 13 | private String locality; 14 | private String city; 15 | private String state; 16 | private int pinCode; 17 | 18 | public StudentAddress() { 19 | // Default constructor 20 | } 21 | 22 | public StudentAddress(String houseNum, String locality, String city, String state, int pinCode) { 23 | this.houseNum = houseNum; 24 | this.locality = locality; 25 | this.city = city; 26 | this.state = state; 27 | this.pinCode = pinCode; 28 | } 29 | 30 | /** 31 | * @return the houseNum 32 | */ 33 | public String getHouseNum() { 34 | return houseNum; 35 | } 36 | 37 | /** 38 | * @param houseNum the houseNum to set 39 | */ 40 | public void setHouseNum(String houseNum) { 41 | this.houseNum = houseNum; 42 | } 43 | 44 | /** 45 | * @return the locality 46 | */ 47 | public String getLocality() { 48 | return locality; 49 | } 50 | 51 | /** 52 | * @param locality the locality to set 53 | */ 54 | public void setLocality(String locality) { 55 | this.locality = locality; 56 | } 57 | 58 | /** 59 | * @return the city 60 | */ 61 | public String getCity() { 62 | return city; 63 | } 64 | 65 | /** 66 | * @param city the city to set 67 | */ 68 | public void setCity(String city) { 69 | this.city = city; 70 | } 71 | 72 | /** 73 | * @return the state 74 | */ 75 | public String getState() { 76 | return state; 77 | } 78 | 79 | /** 80 | * @param state the state to set 81 | */ 82 | public void setState(String state) { 83 | this.state = state; 84 | } 85 | 86 | /** 87 | * @return the pinCode 88 | */ 89 | public int getPinCode() { 90 | return pinCode; 91 | } 92 | 93 | /** 94 | * @param pinCode the pinCode to set 95 | */ 96 | public void setPinCode(int pinCode) { 97 | this.pinCode = pinCode; 98 | } 99 | 100 | @Override 101 | public StudentAddress getClone() { 102 | return new StudentAddress(houseNum, locality, city, state, pinCode); 103 | } 104 | 105 | @Override 106 | public String display() { 107 | return "[" 108 | + "houseNum: " + houseNum 109 | + ", locality: " + locality 110 | + ", city:" + city 111 | + ", state: " + state 112 | + ", pin: " + pinCode 113 | + "]"; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/prototype/StudentRecord.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.prototype; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class StudentRecord implements Prototype { 11 | 12 | private int id; 13 | private int rollNo; 14 | private String name; 15 | private StudentAddress address; 16 | 17 | public StudentRecord() { 18 | // Default Constructor 19 | } 20 | 21 | public StudentRecord(int id, int rollNo, String name, StudentAddress address) { 22 | this.id = id; 23 | this.rollNo = rollNo; 24 | this.name = name; 25 | this.address = address; 26 | } 27 | 28 | /** 29 | * @return the id 30 | */ 31 | public int getId() { 32 | return id; 33 | } 34 | 35 | /** 36 | * @param id the id to set 37 | */ 38 | public void setId(int id) { 39 | this.id = id; 40 | } 41 | 42 | /** 43 | * @return the rollNo 44 | */ 45 | public int getRollNo() { 46 | return rollNo; 47 | } 48 | 49 | /** 50 | * @param rollNo the rollNo to set 51 | */ 52 | public void setRollNo(int rollNo) { 53 | this.rollNo = rollNo; 54 | } 55 | 56 | /** 57 | * @return the name 58 | */ 59 | public String getName() { 60 | return name; 61 | } 62 | 63 | /** 64 | * @param name the name to set 65 | */ 66 | public void setName(String name) { 67 | this.name = name; 68 | } 69 | 70 | /** 71 | * @return the address 72 | */ 73 | public StudentAddress getAddress() { 74 | return address; 75 | } 76 | 77 | /** 78 | * @param address the address to set 79 | */ 80 | public void setAddress(StudentAddress address) { 81 | this.address = address; 82 | } 83 | 84 | @Override 85 | public StudentRecord getClone() { 86 | return new StudentRecord(id, rollNo, name, address.getClone()); 87 | } 88 | 89 | @Override 90 | public String display() { 91 | return "[" 92 | + "id: " + id 93 | + ", rollNo: " + rollNo 94 | + ", name: " + name 95 | + ", address: " + address.display() 96 | + "]"; 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/singleton/MySingleton.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.singleton; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * There are four ways to break the singleton design. 10 | *
    11 | *
  • Instantiate through reflection 12 | *
  • Multiple threads trying to instantiate simultaneously 13 | *
  • Serialization and then de-serialization the object 14 | *
  • By cloning the object 15 | *
16 | * 17 | * Each of the possibilities are prevented by the below implementation. 18 | * 19 | * @author Atanu Bhowmick 20 | * 21 | */ 22 | public class MySingleton implements Cloneable, Serializable { 23 | 24 | private static final long serialVersionUID = -5754920445679992251L; 25 | 26 | private MySingleton() { 27 | MySingleton mySingleton = getInstance(); 28 | if (mySingleton != null) { 29 | throw new IllegalStateException("Singleton class can't be instantiated more than once"); 30 | } 31 | } 32 | 33 | public static MySingleton getInstance() { 34 | return SingletonHelper.INSTANCE; 35 | } 36 | 37 | protected Object readResolve() { 38 | return getInstance(); 39 | } 40 | 41 | @Override 42 | protected Object clone() throws CloneNotSupportedException { 43 | throw new CloneNotSupportedException("Singleton class can't be cloned"); 44 | } 45 | 46 | /** 47 | * This is a helper class to instantiate of the {@link MySingleton} class. 48 | * As this is a static class, would be loaded to memory only once. But this 49 | * is a nested class, so it won't be loaded until called via parent class. 50 | * 51 | * @author Atanu Bhowmick 52 | * 53 | */ 54 | private static final class SingletonHelper { 55 | private static final MySingleton INSTANCE = new MySingleton(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/singleton/SingletonTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.singleton; 5 | 6 | import java.io.FileInputStream; 7 | import java.io.FileOutputStream; 8 | import java.io.IOException; 9 | import java.io.ObjectInputStream; 10 | import java.io.ObjectOutputStream; 11 | import java.lang.reflect.Constructor; 12 | 13 | /** 14 | * @author Atanu Bhowmick 15 | * 16 | */ 17 | public class SingletonTest { 18 | 19 | /** 20 | * @param args 21 | */ 22 | public static void main(String[] args) { 23 | 24 | MySingleton mySingleton = MySingleton.getInstance(); 25 | 26 | testReflection(mySingleton); 27 | 28 | testCloning(mySingleton); 29 | 30 | testSerilizationAndDeserilization(mySingleton); 31 | 32 | testMultiThreading(mySingleton); 33 | } 34 | 35 | private static void testReflection(MySingleton mySingleton) { 36 | System.out.println("Trying to create another instance using reflection"); 37 | System.out.println("Should throw IllegalStateException(Singleton class can't be instantiated more than once)"); 38 | try { 39 | String className = "dev.atanu.design.creational.singleton.MySingleton"; 40 | Class clazz = Class.forName(className); 41 | Constructor[] constructors = clazz.getDeclaredConstructors(); 42 | Constructor constructor = constructors[1]; 43 | constructor.setAccessible(true); 44 | 45 | // Should throw IllegalStateException("Singleton class can't be instantiated 46 | // more than once") 47 | MySingleton mySingleton1 = (MySingleton) constructor.newInstance(); 48 | boolean isSameInstance = mySingleton == mySingleton1; 49 | System.out.println("Instances are equal : " + isSameInstance); 50 | } catch (Exception e) { 51 | System.out.println("Inside catch block - testReflection() "); 52 | e.printStackTrace(); 53 | } 54 | } 55 | 56 | private static void testCloning(MySingleton mySingleton) { 57 | System.out.println("\nTrying to create another instance using cloning"); 58 | try { 59 | // Should throw CloneNotSupportedException("Singleton class can't be cloned") 60 | mySingleton.clone(); 61 | } catch (Exception e) { 62 | System.out.println("Inside catch block - testCloning() - " + e.getMessage()); 63 | e.printStackTrace(); 64 | } 65 | } 66 | 67 | private static void testSerilizationAndDeserilization(MySingleton mySingleton) { 68 | String fileName = "Singleton_test.txt"; 69 | System.out.println("\nTrying serilization & deserilization to validate the instance creation"); 70 | try (FileOutputStream fileOutputStream = new FileOutputStream(fileName); 71 | ObjectOutputStream out = new ObjectOutputStream(fileOutputStream);) { 72 | out.writeObject(mySingleton); 73 | } catch (IOException e) { 74 | e.printStackTrace(); 75 | } 76 | 77 | try (FileInputStream fileInputStream = new FileInputStream(fileName); 78 | ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);) { 79 | Object obj = inputStream.readObject(); 80 | if (obj instanceof MySingleton) { 81 | System.out.println("Deserilize successful"); 82 | MySingleton mySingleton2 = (MySingleton) obj; 83 | boolean isSameObject = mySingleton == mySingleton2; 84 | System.out.println("Same instance returned: " + isSameObject); 85 | } 86 | } catch (IOException | ClassNotFoundException e) { 87 | e.printStackTrace(); 88 | } 89 | } 90 | 91 | /** 92 | * Run this method separately to validate in multi-threading scenario. 93 | * 94 | * @param mySingleton 95 | */ 96 | private static void testMultiThreading(MySingleton mySingleton) { 97 | System.out.println("\nTrying multi threading to validate the instance creation"); 98 | System.out.println("All Validation should be true"); 99 | for (int i = 1; i <= 100; i++) { 100 | new Thread(new SingletonThread(mySingleton), "T" + i).start(); 101 | } 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/creational/singleton/SingletonThread.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.creational.singleton; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class SingletonThread implements Runnable { 11 | 12 | private MySingleton mySingleton; 13 | 14 | public SingletonThread(MySingleton mySingleton) { 15 | this.mySingleton = mySingleton; 16 | } 17 | 18 | @Override 19 | public void run() { 20 | MySingleton mySingleton1 = MySingleton.getInstance(); 21 | boolean sameInstance = this.mySingleton == mySingleton1; 22 | System.out.println(Thread.currentThread().getName() + " is same instance: " + sameInstance); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/adapter/AdapterPatternTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.adapter; 5 | 6 | /** 7 | * https://www.digitalocean.com/community/tutorials/adapter-design-pattern-java 8 | * 9 | * @author Atanu Bhowmick 10 | * 11 | */ 12 | public class AdapterPatternTest { 13 | 14 | /** 15 | * @param args 16 | */ 17 | public static void main(String[] args) { 18 | testClassAdapter(); 19 | testObjectAdapter(); 20 | } 21 | 22 | private static void testObjectAdapter() { 23 | SocketAdapter sockAdapter = new SocketObjectAdapterImpl(); 24 | 25 | Volt v3 = getVolt(sockAdapter, 3); 26 | Volt v12 = getVolt(sockAdapter, 12); 27 | Volt v120 = getVolt(sockAdapter, 120); 28 | 29 | System.out.println("v3 volts using Object Adapter = " + v3.getVolts()); 30 | System.out.println("v12 volts using Object Adapter = " + v12.getVolts()); 31 | System.out.println("v120 volts using Object Adapter = " + v120.getVolts()); 32 | } 33 | 34 | private static void testClassAdapter() { 35 | SocketAdapter sockAdapter = new SocketClassAdapterImpl(); 36 | 37 | Volt v3 = getVolt(sockAdapter, 3); 38 | Volt v12 = getVolt(sockAdapter, 12); 39 | Volt v120 = getVolt(sockAdapter, 120); 40 | 41 | System.out.println("v3 volts using Class Adapter = " + v3.getVolts()); 42 | System.out.println("v12 volts using Class Adapter = " + v12.getVolts()); 43 | System.out.println("v120 volts using Class Adapter = " + v120.getVolts()); 44 | } 45 | 46 | private static Volt getVolt(SocketAdapter sockAdapter, int i) { 47 | switch (i) { 48 | case 3: 49 | return sockAdapter.get3Volt(); 50 | case 12: 51 | return sockAdapter.get12Volt(); 52 | case 120: 53 | return sockAdapter.get120Volt(); 54 | default: 55 | return sockAdapter.get120Volt(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/adapter/Socket.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.adapter; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Socket { 11 | 12 | public Volt getVolt() { 13 | return new Volt(120); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/adapter/SocketAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.adapter; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface SocketAdapter { 11 | 12 | public Volt get120Volt(); 13 | 14 | public Volt get12Volt(); 15 | 16 | public Volt get3Volt(); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/adapter/SocketClassAdapterImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.adapter; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class SocketClassAdapterImpl extends Socket implements SocketAdapter { 11 | 12 | @Override 13 | public Volt get120Volt() { 14 | return getVolt(); 15 | } 16 | 17 | @Override 18 | public Volt get12Volt() { 19 | Volt v = getVolt(); 20 | return convertVolt(v, 10); 21 | } 22 | 23 | @Override 24 | public Volt get3Volt() { 25 | Volt v = getVolt(); 26 | return convertVolt(v, 40); 27 | } 28 | 29 | private Volt convertVolt(Volt v, int i) { 30 | return new Volt(v.getVolts() / i); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/adapter/SocketObjectAdapterImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.adapter; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class SocketObjectAdapterImpl implements SocketAdapter { 11 | 12 | // Using Composition for adapter pattern 13 | private Socket sock = new Socket(); 14 | 15 | @Override 16 | public Volt get120Volt() { 17 | return sock.getVolt(); 18 | } 19 | 20 | @Override 21 | public Volt get12Volt() { 22 | Volt v = sock.getVolt(); 23 | return convertVolt(v, 10); 24 | } 25 | 26 | @Override 27 | public Volt get3Volt() { 28 | Volt v = sock.getVolt(); 29 | return convertVolt(v, 40); 30 | } 31 | 32 | private Volt convertVolt(Volt v, int i) { 33 | return new Volt(v.getVolts() / i); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/adapter/Volt.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.adapter; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Volt { 11 | 12 | private int volts; 13 | 14 | public Volt(int v) { 15 | this.volts = v; 16 | } 17 | 18 | public int getVolts() { 19 | return volts; 20 | } 21 | 22 | public void setVolts(int volts) { 23 | this.volts = volts; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/bridge/BridgePatternTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.bridge; 5 | 6 | /** 7 | * https://www.baeldung.com/java-bridge-pattern 8 | * https://www.digitalocean.com/community/tutorials/bridge-design-pattern-java 9 | * 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public class BridgePatternTest { 14 | 15 | public static void main(String[] args) { 16 | Shape triangle = new Triangle(new RedColor()); 17 | triangle.draw(); 18 | 19 | Shape rectangle = new Rectangle(new GreenColor()); 20 | rectangle.draw(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/bridge/Color.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.bridge; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface Color { 11 | 12 | public void applyColor(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/bridge/GreenColor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.bridge; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class GreenColor implements Color { 11 | 12 | @Override 13 | public void applyColor() { 14 | System.out.println("Applying color - Green"); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/bridge/Rectangle.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.bridge; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Rectangle extends Shape { 11 | 12 | public Rectangle(Color color) { 13 | super(color); 14 | } 15 | 16 | @Override 17 | public void draw() { 18 | System.out.println("Rectangle drawn"); 19 | color.applyColor(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/bridge/RedColor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.bridge; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class RedColor implements Color { 11 | 12 | @Override 13 | public void applyColor() { 14 | System.out.println("Applying color - Red"); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/bridge/Shape.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.bridge; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public abstract class Shape { 11 | 12 | protected Color color; 13 | 14 | public Shape(Color color) { 15 | this.color = color; 16 | } 17 | 18 | public abstract void draw(); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/bridge/Triangle.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.bridge; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Triangle extends Shape { 11 | 12 | public Triangle(Color color) { 13 | super(color); 14 | } 15 | 16 | @Override 17 | public void draw() { 18 | System.out.println("Triangle drawn"); 19 | color.applyColor(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/composite/BusinessAnalyst.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.composite; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class BusinessAnalyst implements Employee { 11 | 12 | private int empId; 13 | private String name; 14 | private String position; 15 | 16 | public BusinessAnalyst(int empId, String name, String position) { 17 | this.empId = empId; 18 | this.name = name; 19 | this.position = position; 20 | } 21 | 22 | @Override 23 | public void showDetails() { 24 | System.out.println("[id = " + empId + ", name = " + name + ", position = " + position + "]"); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/composite/CompositePatternTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.composite; 5 | 6 | /** 7 | * https://www.baeldung.com/java-composite-pattern 8 | * https://www.geeksforgeeks.org/composite-design-pattern/ 9 | * 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public class CompositePatternTest { 14 | 15 | /** 16 | * @param args 17 | */ 18 | public static void main(String[] args) { 19 | Employee developer1 = new Developer(1, "Atanu", "Developer"); 20 | Employee developer2 = new Developer(2, "Dev1", "Senior Developer"); 21 | Employee tester1 = new Tester(3, "Tester1", "Tester"); 22 | 23 | Manager manager1 = new Manager(10, "Manager1", "Project Manager"); 24 | manager1.addReportee(developer1); 25 | manager1.addReportee(developer2); 26 | manager1.addReportee(tester1); 27 | 28 | Employee developer3 = new Developer(1, "Dev3", "Senior Developer"); 29 | Employee ba1 = new BusinessAnalyst(2, "BA1", "Senior BA"); 30 | Employee tester2 = new Tester(3, "Tester2", "Senior Tester"); 31 | 32 | Manager manager2 = new Manager(11, "Manager2", "Delivery Manager"); 33 | manager2.addReportee(developer3); 34 | manager2.addReportee(ba1); 35 | manager2.addReportee(tester2); 36 | 37 | Manager manager3 = new Manager(12, "Director1", "Associate Director"); 38 | manager3.addReportee(manager1); 39 | manager3.addReportee(manager2); 40 | 41 | // Show everyone's details 42 | manager3.showDetails(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/composite/Developer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.composite; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Developer implements Employee { 11 | 12 | private int empId; 13 | private String name; 14 | private String position; 15 | 16 | public Developer(int empId, String name, String position) { 17 | this.empId = empId; 18 | this.name = name; 19 | this.position = position; 20 | } 21 | 22 | @Override 23 | public void showDetails() { 24 | System.out.println("[id = " + empId + ", name = " + name + ", position = " + position + "]"); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/composite/Employee.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.composite; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface Employee { 11 | 12 | public void showDetails(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/composite/Manager.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.composite; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public class Manager implements Employee { 14 | 15 | private int empId; 16 | private String name; 17 | private String position; 18 | 19 | private List reportees; 20 | 21 | public Manager(int empId, String name, String position) { 22 | this.empId = empId; 23 | this.name = name; 24 | this.position = position; 25 | this.reportees = new ArrayList<>(); 26 | } 27 | 28 | @Override 29 | public void showDetails() { 30 | System.out.println("\n[id = " + empId + ", name = " + name + ", position = " + position + "]"); 31 | reportees.stream().forEach(Employee::showDetails); 32 | } 33 | 34 | public void addReportee(Employee reportee) { 35 | this.reportees.add(reportee); 36 | } 37 | 38 | public void removeReportee(Employee reportee) { 39 | if (reportees.contains(reportee)) { 40 | this.reportees.remove(reportee); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/composite/Tester.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.composite; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Tester implements Employee { 11 | 12 | private int empId; 13 | private String name; 14 | private String position; 15 | 16 | public Tester(int empId, String name, String position) { 17 | this.empId = empId; 18 | this.name = name; 19 | this.position = position; 20 | } 21 | 22 | @Override 23 | public void showDetails() { 24 | System.out.println("[id = " + empId + ", name = " + name + ", position = " + position + "]"); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/decorator/CheeseDecorator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.decorator; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class CheeseDecorator extends SandwichDecorator { 11 | 12 | private Sandwich currentSandwich; 13 | 14 | public CheeseDecorator(Sandwich sandwich) { 15 | currentSandwich = sandwich; 16 | } 17 | 18 | @Override 19 | public String getDescription() { 20 | return currentSandwich.getDescription() + ", Cheese"; 21 | } 22 | 23 | @Override 24 | public double price() { 25 | return currentSandwich.price() + 20.0d; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/decorator/ChickenSandwich.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.decorator; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ChickenSandwich extends Sandwich { 11 | 12 | public ChickenSandwich() { 13 | this.description = "Chicken Sandwich"; 14 | } 15 | 16 | @Override 17 | public double price() { 18 | return 50.0d; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/decorator/SaladDecorator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.decorator; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class SaladDecorator extends SandwichDecorator { 11 | 12 | private Sandwich currentSandwich; 13 | 14 | public SaladDecorator(Sandwich sandwich) { 15 | currentSandwich = sandwich; 16 | } 17 | 18 | @Override 19 | public String getDescription() { 20 | return currentSandwich.getDescription() + ", Salad"; 21 | } 22 | 23 | @Override 24 | public double price() { 25 | return currentSandwich.price() + 10.0d; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/decorator/Sandwich.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.decorator; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public abstract class Sandwich { 11 | 12 | protected String description = "Sandwich"; 13 | 14 | public String getDescription() { 15 | return description; 16 | } 17 | 18 | public abstract double price(); 19 | 20 | @Override 21 | public String toString() { 22 | return "Sandwich[" + getDescription() + " - price:" + price() + " INR]"; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/decorator/SandwichDecorator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.decorator; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public abstract class SandwichDecorator extends Sandwich { 11 | 12 | @Override 13 | public abstract double price(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/decorator/SandwichMakerTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.decorator; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class SandwichMakerTest { 11 | 12 | /** 13 | * @param args 14 | */ 15 | public static void main(String[] args) { 16 | Sandwich sandwich = new ChickenSandwich(); 17 | System.out.println(sandwich); 18 | sandwich = new CheeseDecorator(sandwich); 19 | System.out.println(sandwich); 20 | sandwich = new SaladDecorator(sandwich); 21 | System.out.println(sandwich); 22 | 23 | System.out.println("----- Creating another -----"); 24 | 25 | Sandwich vegSandwich = new VegSandwich(); 26 | System.out.println(vegSandwich); 27 | sandwich = new SaladDecorator(vegSandwich); 28 | System.out.println(sandwich); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/decorator/VegSandwich.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.decorator; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class VegSandwich extends Sandwich { 11 | 12 | public VegSandwich() { 13 | this.description = "Veg Sandwich"; 14 | } 15 | 16 | @Override 17 | public double price() { 18 | return 40.0d; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/facade/CardDetails.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.facade; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class CardDetails { 11 | 12 | private CardType cardType; 13 | private String payeeName; 14 | private String cardNumber; 15 | private String cvv; 16 | private String dateOfExpiry; 17 | 18 | public CardDetails(CardType cardType, String payeeName, String cardNumber, String cvv, String dateOfExpiry) { 19 | this.cardType = cardType; 20 | this.payeeName = payeeName; 21 | this.cardNumber = cardNumber; 22 | this.cvv = cvv; 23 | this.dateOfExpiry = dateOfExpiry; 24 | } 25 | 26 | public CardType getCardType() { 27 | return cardType; 28 | } 29 | 30 | public void setCardType(CardType cardType) { 31 | this.cardType = cardType; 32 | } 33 | 34 | public String getPayeeName() { 35 | return payeeName; 36 | } 37 | 38 | public String getCardNumber() { 39 | return cardNumber; 40 | } 41 | 42 | public String getCvv() { 43 | return cvv; 44 | } 45 | 46 | public String getDateOfExpiry() { 47 | return dateOfExpiry; 48 | } 49 | 50 | 51 | public enum CardType { 52 | DEBIT, 53 | CREDIT 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/facade/DeliveryAddress.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.facade; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class DeliveryAddress { 11 | 12 | private String houseNum; 13 | private String locality; 14 | private String city; 15 | private String state; 16 | private int pinCode; 17 | 18 | public DeliveryAddress() { 19 | // Default constructor 20 | } 21 | 22 | public DeliveryAddress(String houseNum, String locality, String city, String state, int pinCode) { 23 | this.houseNum = houseNum; 24 | this.locality = locality; 25 | this.city = city; 26 | this.state = state; 27 | this.pinCode = pinCode; 28 | } 29 | 30 | /** 31 | * @return the houseNum 32 | */ 33 | public String getHouseNum() { 34 | return houseNum; 35 | } 36 | 37 | /** 38 | * @param houseNum the houseNum to set 39 | */ 40 | public void setHouseNum(String houseNum) { 41 | this.houseNum = houseNum; 42 | } 43 | 44 | /** 45 | * @return the locality 46 | */ 47 | public String getLocality() { 48 | return locality; 49 | } 50 | 51 | /** 52 | * @param locality the locality to set 53 | */ 54 | public void setLocality(String locality) { 55 | this.locality = locality; 56 | } 57 | 58 | /** 59 | * @return the city 60 | */ 61 | public String getCity() { 62 | return city; 63 | } 64 | 65 | /** 66 | * @param city the city to set 67 | */ 68 | public void setCity(String city) { 69 | this.city = city; 70 | } 71 | 72 | /** 73 | * @return the state 74 | */ 75 | public String getState() { 76 | return state; 77 | } 78 | 79 | /** 80 | * @param state the state to set 81 | */ 82 | public void setState(String state) { 83 | this.state = state; 84 | } 85 | 86 | /** 87 | * @return the pinCode 88 | */ 89 | public int getPinCode() { 90 | return pinCode; 91 | } 92 | 93 | /** 94 | * @param pinCode the pinCode to set 95 | */ 96 | public void setPinCode(int pinCode) { 97 | this.pinCode = pinCode; 98 | } 99 | 100 | public String display() { 101 | return "[" + "houseNum: " + houseNum + ", locality: " + locality + ", city:" + city + ", state: " + state 102 | + ", pin: " + pinCode + "]"; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/facade/DeliveryService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.facade; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class DeliveryService { 11 | 12 | private DeliveryAddress address; 13 | 14 | public void deliver(DeliveryAddress address) { 15 | shipping(); 16 | System.out.println("Order sent to currier"); 17 | outForDelivery(); 18 | } 19 | 20 | private void shipping() { 21 | System.out.println("Shipping products"); 22 | } 23 | 24 | private void outForDelivery() { 25 | System.out.println("The products are out for delivery"); 26 | } 27 | 28 | public DeliveryAddress getAddress() { 29 | return address; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/facade/FacadePatternTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.facade; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import dev.atanu.design.structural.facade.CardDetails.CardType; 10 | 11 | /** 12 | * https://www.scaler.com/topics/design-patterns/facade-design-patterns/ 13 | * 14 | * @author Atanu Bhowmick 15 | * 16 | */ 17 | public class FacadePatternTest { 18 | 19 | /** 20 | * @param args 21 | */ 22 | public static void main(String[] args) { 23 | 24 | Operator operator = new Operator(); 25 | 26 | List products = new ArrayList<>(); 27 | products.add(new Product(1L, "HP Pavilion Laptop", 45000.00, "14 Inch", "HP")); 28 | products.add(new Product(2L, "Samsung Galaxy s7", 20000.00, "6 Inch", "Samsung")); 29 | CardDetails creditCard = new CardDetails(CardType.CREDIT, "Atanu", "1234567890123456", "000", "01/2030"); 30 | DeliveryAddress address = new DeliveryAddress("A12", "AJ Street", "Kolkata", "WB", 700001); 31 | operator.completeOrder(products, creditCard, address); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/facade/Operator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.facade; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author Atanu Bhowmick 10 | * 11 | */ 12 | public class Operator { 13 | 14 | private OrderService orderService; 15 | private PaymentService paymentService; 16 | private DeliveryService deliveryService; 17 | 18 | public Operator() { 19 | this.orderService = new OrderService(); 20 | this.paymentService = new PaymentService(); 21 | this.deliveryService = new DeliveryService(); 22 | } 23 | 24 | public void completeOrder(List products, CardDetails cardDetails, DeliveryAddress address) { 25 | double amount = orderService.createOrder(products); 26 | boolean isPaymentSuccess = paymentService.makePayment(amount, cardDetails); 27 | if(isPaymentSuccess) { 28 | deliveryService.deliver(address); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/facade/OrderService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.facade; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author Atanu Bhowmick 10 | * 11 | */ 12 | public class OrderService { 13 | 14 | private List products; 15 | 16 | public double createOrder(List products) { 17 | this.products = products; 18 | System.out.println("Order created"); 19 | return products.stream().map(Product::getProductPrice).mapToDouble(d -> d).sum(); 20 | } 21 | 22 | public List getProducts() { 23 | return products; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/facade/PaymentService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.facade; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class PaymentService { 11 | 12 | public boolean makePayment(double amount, CardDetails cardDetails) { 13 | System.out.println("Making payment of " + amount); 14 | return completePayment(amount, cardDetails); 15 | } 16 | 17 | private boolean completePayment(double amount, CardDetails cardDetails) { 18 | System.out.println("Calling payment gateway.."); 19 | // Code to call payment gateway 20 | System.out.println("Payment done with " + cardDetails.getCardType() + " ends with " 21 | + cardDetails.getCardNumber().substring(12)); 22 | return true; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/facade/Product.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.facade; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class Product { 11 | 12 | private Long productId; 13 | private String productName; 14 | private Double productPrice; 15 | private String productSize; 16 | private String brandName; 17 | 18 | public Product() { 19 | // No-arg constructor 20 | } 21 | 22 | public Product(Long productId, String productName, Double productPrice, String productSize, String brandName) { 23 | this.productId = productId; 24 | this.productName = productName; 25 | this.productPrice = productPrice; 26 | this.productSize = productSize; 27 | this.brandName = brandName; 28 | } 29 | 30 | public Long getProductId() { 31 | return productId; 32 | } 33 | 34 | public void setProductId(Long productId) { 35 | this.productId = productId; 36 | } 37 | 38 | public String getProductName() { 39 | return productName; 40 | } 41 | 42 | public void setProductName(String productName) { 43 | this.productName = productName; 44 | } 45 | 46 | public Double getProductPrice() { 47 | return productPrice; 48 | } 49 | 50 | public void setProductPrice(Double productPrice) { 51 | this.productPrice = productPrice; 52 | } 53 | 54 | public String getProductSize() { 55 | return productSize; 56 | } 57 | 58 | public void setProductSize(String productSize) { 59 | this.productSize = productSize; 60 | } 61 | 62 | public String getBrandName() { 63 | return brandName; 64 | } 65 | 66 | public void setBrandName(String brandName) { 67 | this.brandName = brandName; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/flyweight/Brush.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.flyweight; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface Brush { 11 | 12 | public void setColor(String color); 13 | 14 | public void draw(String content); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/flyweight/BrushFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package dev.atanu.design.structural.flyweight; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /** 10 | * @author Atanu Bhowmick 11 | * 12 | */ 13 | public class BrushFactory { 14 | private static final Map BRUSH_MAP_CACHE = new HashMap<>(); 15 | 16 | public static Brush getThickBrush(String color) { 17 | String key = color + "-THICK"; 18 | Brush brush = BRUSH_MAP_CACHE.get(key); 19 | 20 | if (brush == null) { 21 | brush = new ThickBrush(); 22 | brush.setColor(color); 23 | BRUSH_MAP_CACHE.put(key, brush); 24 | } 25 | return brush; 26 | } 27 | 28 | public static Brush getThinBrush(String color) { 29 | String key = color + "-THIN"; 30 | Brush brush = BRUSH_MAP_CACHE.get(key); 31 | 32 | if (brush == null) { 33 | brush = new ThinBrush(); 34 | brush.setColor(color); 35 | BRUSH_MAP_CACHE.put(key, brush); 36 | } 37 | return brush; 38 | } 39 | 40 | public static Brush getMediumBrush(String color) { 41 | String key = color + "-MEDIUM"; 42 | Brush brush = BRUSH_MAP_CACHE.get(key); 43 | 44 | if (brush == null) { 45 | brush = new MediumBrush(); 46 | brush.setColor(color); 47 | BRUSH_MAP_CACHE.put(key, brush); 48 | } 49 | 50 | return brush; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/flyweight/BrushSize.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.flyweight; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public enum BrushSize { 11 | 12 | THIN, 13 | MEDIUM, 14 | THICK 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/flyweight/FlyweightPatternTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package dev.atanu.design.structural.flyweight; 5 | 6 | /** 7 | * https://www.javadevjournal.com/java-design-patterns/flyweight-design-pattern/ 8 | * 9 | * @author Atanu Bhowmick 10 | * 11 | */ 12 | public class FlyweightPatternTest { 13 | 14 | public static void main(String[] args) { 15 | Brush redThickBrush1 = BrushFactory.getThickBrush("RED"); 16 | redThickBrush1.draw("Hello There !!"); 17 | 18 | // Red Brush is shared 19 | Brush redThickBrush2 = BrushFactory.getThickBrush("RED"); 20 | redThickBrush2.draw("Hello There Again !!"); 21 | 22 | System.out.println("Hashcode: " + redThickBrush1.hashCode()); 23 | System.out.println("Hashcode: " + redThickBrush2.hashCode()); 24 | 25 | // New thin Blue Brush 26 | Brush blueThinBrush1 = BrushFactory.getThinBrush("BLUE"); // created new pen 27 | blueThinBrush1.draw("Hello There !!"); 28 | 29 | // Blue Brush is shared 30 | Brush blueThinBrush2 = BrushFactory.getThinBrush("BLUE"); // created new pen 31 | blueThinBrush2.draw("Hello There Again!!"); 32 | 33 | System.out.println("Hashcode: " + blueThinBrush1.hashCode()); 34 | System.out.println("Hashcode: " + blueThinBrush2.hashCode()); 35 | 36 | // New MEDIUM Yellow Brush 37 | Brush yellowThinBrush1 = BrushFactory.getMediumBrush("YELLOW"); 38 | yellowThinBrush1.draw("Hello There !!"); 39 | 40 | // Yellow brush is shared 41 | Brush yellowThinBrush2 = BrushFactory.getMediumBrush("YELLOW"); 42 | yellowThinBrush2.draw("Hello There Again!!"); 43 | 44 | System.out.println("Hashcode: " + yellowThinBrush1.hashCode()); 45 | System.out.println("Hashcode: " + yellowThinBrush2.hashCode()); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/flyweight/MediumBrush.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.flyweight; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class MediumBrush implements Brush { 11 | 12 | private String color; 13 | final BrushSize brushSize = BrushSize.THIN; 14 | 15 | @Override 16 | public void setColor(String color) { 17 | this.color = color; 18 | } 19 | 20 | @Override 21 | public void draw(String content) { 22 | System.out.println("Drawing '" + content + "' in " + brushSize + " color : " + color); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/flyweight/ThickBrush.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.flyweight; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ThickBrush implements Brush { 11 | 12 | private String color; 13 | final BrushSize brushSize = BrushSize.THICK; 14 | 15 | @Override 16 | public void setColor(String color) { 17 | this.color = color; 18 | } 19 | 20 | @Override 21 | public void draw(String content) { 22 | System.out.println("Drawing '" + content + "' in " + brushSize + " color : " + color); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/flyweight/ThinBrush.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.flyweight; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ThinBrush implements Brush { 11 | 12 | private String color; 13 | final BrushSize brushSize = BrushSize.MEDIUM; 14 | 15 | @Override 16 | public void setColor(String color) { 17 | this.color = color; 18 | } 19 | 20 | @Override 21 | public void draw(String content) { 22 | System.out.println("Drawing '" + content + "' in " + brushSize + " color : " + color); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/proxy/InternetAccess.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.proxy; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public interface InternetAccess { 11 | 12 | public boolean grantInternetAccess(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/proxy/ProxyInternetAccess.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.proxy; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class ProxyInternetAccess implements InternetAccess { 11 | 12 | private String employeeName; 13 | 14 | public ProxyInternetAccess(String employeeName) { 15 | this.employeeName = employeeName; 16 | } 17 | 18 | @Override 19 | public boolean grantInternetAccess() { 20 | if (getRole(employeeName) > 4) { 21 | InternetAccess realAccess = new RealInternetAccess(employeeName); 22 | return realAccess.grantInternetAccess(); 23 | } else { 24 | System.out.println("No Internet access granted. Your job level is below 5"); 25 | return false; 26 | } 27 | } 28 | 29 | public int getRole(String empName) { 30 | // Check role from the database based on Name and designation 31 | // return job level or job designation. 32 | return 9; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/proxy/ProxyPatternClientTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.proxy; 5 | 6 | /** 7 | * https://www.javatpoint.com/proxy-pattern 8 | * 9 | * @author Atanu Bhowmick 10 | * 11 | */ 12 | public class ProxyPatternClientTest { 13 | 14 | public static void main(String[] args) { 15 | InternetAccess access = new ProxyInternetAccess("Ashwin Rajput"); 16 | access.grantInternetAccess(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/dev/atanu/design/structural/proxy/RealInternetAccess.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package dev.atanu.design.structural.proxy; 5 | 6 | /** 7 | * @author Atanu Bhowmick 8 | * 9 | */ 10 | public class RealInternetAccess implements InternetAccess { 11 | 12 | private String employeeName; 13 | 14 | public RealInternetAccess(String empName) { 15 | this.employeeName = empName; 16 | } 17 | 18 | @Override 19 | public boolean grantInternetAccess() { 20 | System.out.println("Internet Access granted for employee: " + employeeName); 21 | return true; 22 | } 23 | } 24 | --------------------------------------------------------------------------------