├── .gitignore ├── .idea ├── .gitignore ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── uiDesigner.xml ├── README.md ├── designpatterns.iml ├── out └── production │ └── designpatterns │ ├── behavioral │ └── Behavioral Design Patterns.md │ ├── creational │ ├── Creational Design Patterns.md │ ├── abstractfactory │ │ ├── AbstractFactory.class │ │ ├── BankFactory$1.class │ │ ├── BankFactory.class │ │ ├── Driver.class │ │ ├── LoanFactory$1.class │ │ ├── LoanFactory.class │ │ ├── ObjectType.class │ │ ├── bank │ │ │ ├── Bank.class │ │ │ ├── BankType.class │ │ │ ├── HDFC.class │ │ │ ├── ICICI.class │ │ │ └── SBI.class │ │ ├── exception │ │ │ └── ObjectCreationException.class │ │ └── loan │ │ │ ├── EducationalLoan.class │ │ │ ├── HomeLoan.class │ │ │ ├── Loan.class │ │ │ ├── LoanType.class │ │ │ └── PersonalLoan.class │ └── factory │ │ ├── Factory.Md │ │ └── notification │ │ ├── Driver.class │ │ ├── EmailNotification.class │ │ ├── Notification.class │ │ ├── NotificationAttributes.class │ │ ├── NotificationFactory.class │ │ ├── NotificationType.class │ │ ├── PushNotification.class │ │ └── SMSNotification.class │ └── structural │ └── Structural Design Patterns.md └── src ├── behavioral ├── Behavioral Design Patterns.md ├── Iterator │ ├── Main.java │ ├── generic │ │ ├── Input.java │ │ ├── InputCollection.java │ │ ├── InputIterator.java │ │ ├── InputIteratorImpl.java │ │ └── Main.java │ ├── iterator.md │ ├── iterator.png │ └── withoutgeneric │ │ ├── Hero.java │ │ ├── HeroCollection.java │ │ ├── HeroIterator.java │ │ ├── HeroIteratorImpl.java │ │ └── Main.java ├── chainofresponsibility │ ├── atmexample │ │ ├── Currency.java │ │ ├── Dollar100Dispenser.java │ │ ├── Dollar2000Dispenser.java │ │ ├── Dollar500Dispenser.java │ │ ├── DollarDispenser.java │ │ ├── Main.java │ │ └── ValidateDollarDispenser.java │ ├── authexample │ │ ├── AuthenticationProcessor.java │ │ ├── Main.java │ │ ├── OAuthProcessor.java │ │ ├── TokenBasedProcessor.java │ │ └── UserNamePasswordProcessor.java │ ├── chain_of_responsibility.md │ ├── cop.draw.png │ └── cor.png ├── command │ ├── cartexample │ │ ├── FoodDeliveryException.java │ │ ├── FoodMenuService.java │ │ ├── Main.java │ │ ├── data │ │ │ ├── CartData.java │ │ │ └── FoodMenuData.java │ │ ├── model │ │ │ ├── FoodMenu.java │ │ │ ├── MealType.java │ │ │ └── MenuItem.java │ │ └── pattern │ │ │ ├── AddCartCommandExecutor.java │ │ │ ├── CartCommandExecutor.java │ │ │ ├── CartCommandType.java │ │ │ └── RemoveCartCommandExecutor.java │ ├── command.md │ ├── command.png │ ├── command_sketch.png │ └── remoteexample │ │ ├── Command.java │ │ ├── Garage.java │ │ ├── GarageDoorClosedCommand.java │ │ ├── GarageDoorOpenCommand.java │ │ ├── Light.java │ │ ├── LightOffCommand.java │ │ ├── LightOnCommand.java │ │ ├── Main.java │ │ ├── RemoteControl.java │ │ └── SlotType.java ├── mediator │ ├── ChatMediator.java │ ├── ChatMediatorImpl.java │ ├── Main.java │ ├── User.java │ ├── UserImpl.java │ ├── mediator.md │ ├── mediator.png │ └── mediator_sketch.png ├── memento │ ├── example1 │ │ ├── AccessTime.java │ │ ├── Checkpoint.java │ │ ├── Main.java │ │ └── TimeState.java │ ├── example2 │ │ ├── Main.java │ │ ├── TextEditor.java │ │ ├── TextWindow.java │ │ └── TextWindowMemento.java │ ├── memento.md │ ├── memento.png │ └── memento_sketch.png ├── observer │ ├── observer.md │ ├── observer.png │ ├── withlibraray │ │ ├── Driver.java │ │ ├── NewsSubscriber.java │ │ ├── Producer.java │ │ └── SocialMediaSubscriber.java │ └── withoutlibrary │ │ ├── Driver.java │ │ ├── NewsSubscriber.java │ │ ├── Producer.java │ │ ├── SocialMediaSubscriber.java │ │ └── Subscriber.java ├── state │ ├── DeliveredState.java │ ├── Main.java │ ├── OrderedState.java │ ├── Package.java │ ├── PackageState.java │ ├── ReceivedState.java │ ├── state.md │ └── state.png ├── strategy │ ├── Data.java │ ├── HTMLProcessor.java │ ├── JSONProcessor.java │ ├── META_DATA.java │ ├── Main.java │ ├── PlainTextProcessor.java │ ├── Processor.java │ ├── strategy.md │ └── strategy.png ├── templatemethod │ ├── Main.java │ ├── NonVegPizzaMaker.java │ ├── PizzaMaker.java │ ├── VegPizzaMaker.java │ ├── tempalte_method.md │ └── tenplate.png └── visitor │ ├── AreaVisitor.java │ ├── Circle.java │ ├── Main.java │ ├── PerimeterVisitor.java │ ├── Rectangle.java │ ├── Shape.java │ ├── ShapeVisitor.java │ ├── Square.java │ ├── visitor.md │ ├── visitor.png │ └── visitor_exp.png ├── creational ├── Creational Design Patterns.md ├── abstractfactory │ ├── AbstractFactory.java │ ├── AbstractFactory.md │ ├── AbstractFactoryProvider.java │ ├── BankFactory.java │ ├── Driver.java │ ├── LoanFactory.java │ ├── ObjectType.java │ ├── bank │ │ ├── Bank.java │ │ ├── BankType.java │ │ ├── HDFC.java │ │ ├── ICICI.java │ │ └── SBI.java │ ├── exception │ │ └── ObjectCreationException.java │ ├── img.png │ └── loan │ │ ├── EducationalLoan.java │ │ ├── HomeLoan.java │ │ ├── Loan.java │ │ ├── LoanType.java │ │ └── PersonalLoan.java ├── builder │ ├── Builder.md │ ├── Driver.java │ ├── User.java │ ├── builder.png │ ├── withoutpriorityfields │ │ └── Car.java │ └── withpriorityfields │ │ ├── Car.java │ │ ├── CarBuilder.java │ │ ├── Color.java │ │ ├── EnginePower.java │ │ └── SeatCapacity.java ├── factory │ ├── Factory.md │ ├── createobject │ │ ├── Driver.java │ │ ├── Resource1.java │ │ ├── Resource2.java │ │ └── Resource3.java │ ├── factory.png │ ├── notification │ │ ├── Driver.java │ │ ├── EmailNotification.java │ │ ├── Notification.java │ │ ├── NotificationAttributes.java │ │ ├── NotificationFactory.java │ │ ├── NotificationType.java │ │ ├── PushNotification.java │ │ └── SMSNotification.java │ └── notificationwithoutpattern │ │ ├── Driver.java │ │ ├── EmailNotification.java │ │ ├── Notification.java │ │ ├── NotificationAttributes.java │ │ ├── PushNotification.java │ │ └── SMSNotification.java ├── prototype │ ├── Driver.java │ ├── Employee.java │ ├── Prototype.java │ ├── prototype.md │ └── prototype.png └── singleton │ ├── BillPughSingleton.java │ ├── DoubleLockSingleton.java │ ├── Driver.java │ ├── EagerSingleton.java │ ├── EnumBasedSingleton.java │ ├── NormalSingleton.java │ ├── StaticBlockSingleton.java │ ├── singleton.md │ └── singleton.png └── structural ├── Structural Design Patterns.md ├── adaptor ├── adaptor.md ├── adaptor.png ├── adaptor_sketch.png └── objectadaptor │ ├── Adaptor.java │ ├── Driver.java │ ├── client │ ├── Client.java │ ├── ClientInterface.java │ └── JSONObject.java │ └── vendor │ ├── XMLObject.java │ └── XMLVendor.java ├── bridge ├── Driver.java ├── babstraction │ ├── Circle.java │ ├── Rectangle.java │ ├── Shape.java │ └── Triangle.java ├── binterface │ ├── BlackColor.java │ ├── Color.java │ ├── RedColor.java │ └── WhiteColor.java ├── bridge.md ├── bridge_car.png └── img.png ├── composite ├── Ceo.java ├── Developer.java ├── Driver.java ├── Driver2.java ├── Employee.java ├── Employeer.java ├── Manager.java ├── Position.java ├── ProductOwner.java ├── composite.md ├── composite.png └── composite_org.png ├── decorator ├── BasicCar.java ├── Car.java ├── CarDecorator.java ├── Driver.java ├── LuxuryCar.java ├── SportsCar.java ├── decorator.md └── decorator.png ├── facade ├── AudioMixer.java ├── BitrateReader.java ├── CodecFactory.java ├── CompressionCodec.java ├── MPEG4CompressionCodec.java ├── OggCompressionCodec.java ├── VideoFile.java ├── codec_file.ogg ├── facade.md ├── facade.png ├── facde_exp.png ├── withfacade │ ├── Client.java │ └── VideoConverterFacade.java └── withoutfacade │ └── Client.java ├── flyweight ├── Car.java ├── CarFactory.java ├── CarType.java ├── Driver.java ├── McLearnCar.java ├── PorscheCar.java ├── exception │ └── ObjectCreationException.java ├── flyweight.md └── flyweight.png └── proxy ├── img.png ├── protection ├── Driver.java ├── Internet.java ├── Properties.java ├── ProxyInternet.java └── RealInternet.java ├── proxy.drawio.png ├── proxy.md └── virtual ├── Book.java ├── Driver.java ├── OriginalBook.java └── ProxyBook.java /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | .idea 3 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GOFDesignPatterns 2 | 3 | **Full Playlist** : https://youtube.com/playlist?list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK 4 | 5 | ### Creational Design patterns 6 | * [**Factory Design Pattern**](src/creational/factory/Factory.md) - [**Video Explanation**](https://www.youtube.com/watch?v=ddsqo1Ug1sY&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=2&pp=gAQBiAQB) 7 | * [**Abstract Factory Design Pattern**](src/creational/abstractfactory/AbstractFactory.md) - [**Video Explanation**](https://www.youtube.com/watch?v=UvJVE4wiFi0&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=3&pp=gAQBiAQB) 8 | * [**Builder Design Pattern**](src/creational/builder/Builder.md) - [**Video Explanation**](https://www.youtube.com/watch?v=EfuA9_2QQcM&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=4&pp=gAQBiAQB) 9 | * [**Prototype Design Pattern**](src/creational/prototype/prototype.md) - [**Video Explanation**](https://www.youtube.com/watch?v=tJA1oOl-PpI&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=5&pp=gAQBiAQB) 10 | * [**Singleton Design Pattern**](src/creational/singleton/singleton.md) - [**Video Explanation**](https://www.youtube.com/watch?v=xfuMSZAYwy0&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=6&pp=gAQBiAQB) 11 | 12 | ### Structural Design patterns 13 | * [**Adaptor Design Pattern**](src/structural/adaptor/adaptor.md) - [**Video Explanation**](https://www.youtube.com/watch?v=mhBRXspL92U&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=7&pp=gAQBiAQB) 14 | * [**Proxy Design Pattern**](src/structural/proxy/proxy.md) - [**Video Explanation**](https://www.youtube.com/watch?v=6_2CF-Ra0AY&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=8&t=7s&pp=gAQBiAQB) 15 | * [**Decorator Design Pattern**](src/structural/decorator/decorator.md) - [**Video Explanation**](https://www.youtube.com/watch?v=E8-wTMs79pU&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=9&pp=gAQBiAQB) 16 | * [**Bridge Design Pattern**](src/structural/bridge/bridge.md)- [**Video Explanation**](https://www.youtube.com/watch?v=nMv_jfbRiGo&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=10&pp=gAQBiAQB) 17 | * [**Composite Design Pattern**](src/structural/composite/composite.md) - [**Video Explanation**](https://www.youtube.com/watch?v=KD1v_7mnYhA&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=11&pp=gAQBiAQB) 18 | * [**Facade Design Pattern**](src/structural/facade/facade.md) - [**Video Explanation**](https://www.youtube.com/watch?v=_wXkrceYJWA&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=12&pp=gAQBiAQB) 19 | * [**Flyweight Design Pattern**](src/structural/flyweight/flyweight.md) - [**Video Explanation**](https://www.youtube.com/watch?v=QVxI4W65TAA&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=13&pp=gAQBiAQB) 20 | 21 | ### Behavioural Design patterns 22 | * [**Chain Of Responsibility Design Pattern**](src/behavioral/chainofresponsibility/chain_of_responsibility.md) - [**Video Explanation**](https://www.youtube.com/watch?v=5uBhRUSen7s&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=14&pp=gAQBiAQB) 23 | * [**Command Design Pattern**](src/behavioral/command/command.md) - [**Video Explanation**](https://www.youtube.com/watch?v=S33KwKzMe8s&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=15&pp=gAQBiAQB) 24 | * [**Iterator Design Pattern**](src/behavioral/Iterator/iterator.md) - [**Video Explanation**](https://www.youtube.com/watch?v=WIBlhs4pqd0&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=16&pp=gAQBiAQB) 25 | * [**Mediator Design Pattern**](src/behavioral/mediator/mediator.md) - [**Video Explanation**](https://www.youtube.com/watch?v=9Cm6pSZlZwc&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=17&pp=gAQBiAQB) 26 | * [**Memento Design Pattern**](src/behavioral/memento/memento.md) - [**Video Explanation**](https://www.youtube.com/watch?v=t7gl1Hktwdc&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=18&pp=gAQBiAQB) 27 | * [**Observer Design Pattern**](src/behavioral/observer/observer.md) - [**Video Explanation**](https://www.youtube.com/watch?v=foxHOu5YT_o&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=20&pp=gAQBiAQBsAQB) 28 | * [**State Design Pattern**](src/behavioral/state/state.md) - [**Video Explanation**](https://www.youtube.com/watch?v=mR46hg2e8pU&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=21&pp=gAQBiAQBsAQB) 29 | * [**Strategy Design Pattern**](src/behavioral/strategy/strategy.md) - [**Video Explanation**](https://www.youtube.com/watch?v=ddsqo1Ug1sY&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=2&pp=gAQBiAQB) 30 | * [**Template Method Design Pattern**](src/behavioral/templatemethod/tempalte_method.md) - [**Video Explanation**](https://www.youtube.com/watch?v=ies_MAFXIBc&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=22&pp=gAQBiAQBsAQB) 31 | * [**Visitor Design Pattern**](src/behavioral/visitor/visitor.md) - [**Video Explanation**](https://www.youtube.com/watch?v=SK50E5CAzr0&list=PLyjE_CyqGikoF0dpijEH7RBzZ6KGhRxkK&index=23&pp=gAQBiAQBsAQB) 32 | 33 | -------------------------------------------------------------------------------- /designpatterns.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /out/production/designpatterns/behavioral/Behavioral Design Patterns.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/behavioral/Behavioral Design Patterns.md -------------------------------------------------------------------------------- /out/production/designpatterns/creational/Creational Design Patterns.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/Creational Design Patterns.md -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/AbstractFactory.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/AbstractFactory.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/BankFactory$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/BankFactory$1.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/BankFactory.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/BankFactory.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/Driver.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/Driver.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/LoanFactory$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/LoanFactory$1.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/LoanFactory.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/LoanFactory.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/ObjectType.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/ObjectType.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/bank/Bank.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/bank/Bank.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/bank/BankType.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/bank/BankType.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/bank/HDFC.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/bank/HDFC.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/bank/ICICI.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/bank/ICICI.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/bank/SBI.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/bank/SBI.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/exception/ObjectCreationException.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/exception/ObjectCreationException.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/loan/EducationalLoan.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/loan/EducationalLoan.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/loan/HomeLoan.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/loan/HomeLoan.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/loan/Loan.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/loan/Loan.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/loan/LoanType.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/loan/LoanType.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/abstractfactory/loan/PersonalLoan.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/abstractfactory/loan/PersonalLoan.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/factory/Factory.Md: -------------------------------------------------------------------------------- 1 | **Intent** 2 | ---------- 3 | Define an interface for creating an object, but let subclasses decide which class to 4 | instantiate. Factory Method lets a class defer instantiation to subclasses. 5 | 6 | Also called - *Virtual Constructor* 7 | 8 | It promotes the loose-coupling by eliminating the need to bind application-specific classes into the code. 9 | 10 | ![factory.png](factory.png) -------------------------------------------------------------------------------- /out/production/designpatterns/creational/factory/notification/Driver.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/factory/notification/Driver.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/factory/notification/EmailNotification.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/factory/notification/EmailNotification.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/factory/notification/Notification.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/factory/notification/Notification.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/factory/notification/NotificationAttributes.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/factory/notification/NotificationAttributes.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/factory/notification/NotificationFactory.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/factory/notification/NotificationFactory.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/factory/notification/NotificationType.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/factory/notification/NotificationType.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/factory/notification/PushNotification.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/factory/notification/PushNotification.class -------------------------------------------------------------------------------- /out/production/designpatterns/creational/factory/notification/SMSNotification.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/creational/factory/notification/SMSNotification.class -------------------------------------------------------------------------------- /out/production/designpatterns/structural/Structural Design Patterns.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/out/production/designpatterns/structural/Structural Design Patterns.md -------------------------------------------------------------------------------- /src/behavioral/Behavioral Design Patterns.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/Behavioral Design Patterns.md -------------------------------------------------------------------------------- /src/behavioral/Iterator/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.Iterator; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | 6 | public class Main { 7 | public static void main(String[] args) { 8 | ArrayList arrayList = new ArrayList<>(); 9 | arrayList.add("One"); 10 | arrayList.add("Two"); 11 | arrayList.add("Three"); 12 | 13 | Iterator iterator = arrayList.iterator(); 14 | 15 | while (iterator.hasNext()){ 16 | System.out.println(iterator.next()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/behavioral/Iterator/generic/Input.java: -------------------------------------------------------------------------------- 1 | package behavioral.Iterator.generic; 2 | 3 | public class Input { 4 | 5 | private final String data; 6 | 7 | public Input(String data) { 8 | this.data = data; 9 | } 10 | 11 | public String getData() { 12 | return data; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/behavioral/Iterator/generic/InputCollection.java: -------------------------------------------------------------------------------- 1 | package behavioral.Iterator.generic; 2 | 3 | public class InputCollection { 4 | 5 | Object[] objects; 6 | int index; 7 | 8 | public InputCollection(int n){ 9 | objects = new Object[n]; 10 | index = 0; 11 | } 12 | 13 | public void addData(Input object){ 14 | objects[index] = object; 15 | index++; 16 | } 17 | 18 | public InputIterator iterator(){ 19 | return new InputIteratorImpl(objects); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/behavioral/Iterator/generic/InputIterator.java: -------------------------------------------------------------------------------- 1 | package behavioral.Iterator.generic; 2 | 3 | public interface InputIterator { 4 | 5 | boolean hasNext(); 6 | 7 | E next(); 8 | } 9 | -------------------------------------------------------------------------------- /src/behavioral/Iterator/generic/InputIteratorImpl.java: -------------------------------------------------------------------------------- 1 | package behavioral.Iterator.generic; 2 | 3 | public class InputIteratorImpl implements InputIterator { 4 | 5 | Object[] objects; 6 | int cursor; 7 | int length; 8 | 9 | InputIteratorImpl(Object[] objects){ 10 | this.objects = objects; 11 | cursor = 0; 12 | length = objects.length; 13 | } 14 | 15 | @Override 16 | public boolean hasNext() { 17 | return cursor < objects.length; 18 | } 19 | 20 | @Override 21 | @SuppressWarnings("unchecked") 22 | public E next() { 23 | return (E) objects[cursor++]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/behavioral/Iterator/generic/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.Iterator.generic; 2 | 3 | import behavioral.Iterator.withoutgeneric.Hero; 4 | import behavioral.Iterator.withoutgeneric.HeroCollection; 5 | import behavioral.Iterator.withoutgeneric.HeroIterator; 6 | 7 | public class Main { 8 | public static void main(String[] args) { 9 | InputCollection inputCollection = new InputCollection<>(5); 10 | 11 | inputCollection.addData(new Input("NTR Jr")); 12 | inputCollection.addData(new Input("Prabhas")); 13 | inputCollection.addData(new Input("Yash")); 14 | inputCollection.addData(new Input("Allu Arjun")); 15 | inputCollection.addData(new Input("Rishab Shetty")); 16 | 17 | InputIterator iterator = inputCollection.iterator(); 18 | 19 | while (iterator.hasNext()){ 20 | System.out.println(iterator.next().getData()); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/behavioral/Iterator/iterator.md: -------------------------------------------------------------------------------- 1 | Intent 2 | --------- 3 | *Provide a way to access the elements of an aggregate object sequentially without 4 | exposing its underlying representation.* 5 | 6 | 1. The key idea in this pattern is to take the responsibility for access and traversal out of the list object 7 | and put it into an iterator object. 8 | 2. The Iterator class defines an interface for accessing the list's elements. An iterator object is responsible 9 | for keeping track of the current element; that is, it knows which elements have been traversed already. 10 | 11 | ![iterator.png](iterator.png) 12 | 13 | Overall, the Iterator design pattern is a useful tool for encapsulating the logic for accessing elements of a collection, making it easier to write code that works with a variety of different collections in a uniform manner. -------------------------------------------------------------------------------- /src/behavioral/Iterator/iterator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/Iterator/iterator.png -------------------------------------------------------------------------------- /src/behavioral/Iterator/withoutgeneric/Hero.java: -------------------------------------------------------------------------------- 1 | package behavioral.Iterator.withoutgeneric; 2 | 3 | public class Hero { 4 | private final String name; 5 | 6 | public Hero(String name) { 7 | this.name = name; 8 | } 9 | 10 | public String getName() { 11 | return name; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/behavioral/Iterator/withoutgeneric/HeroCollection.java: -------------------------------------------------------------------------------- 1 | package behavioral.Iterator.withoutgeneric; 2 | 3 | public class HeroCollection { 4 | 5 | Hero[] heroes; 6 | int index; 7 | 8 | public HeroCollection(int n){ 9 | heroes = new Hero[n]; 10 | index = 0; 11 | } 12 | 13 | public void addHero(Hero hero){ 14 | heroes[index] = hero; 15 | index++; 16 | } 17 | 18 | public HeroIterator iterator(){ 19 | return new HeroIteratorImpl(heroes); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/behavioral/Iterator/withoutgeneric/HeroIterator.java: -------------------------------------------------------------------------------- 1 | package behavioral.Iterator.withoutgeneric; 2 | 3 | public interface HeroIterator { 4 | 5 | boolean hasNext(); 6 | 7 | Hero next(); 8 | } 9 | -------------------------------------------------------------------------------- /src/behavioral/Iterator/withoutgeneric/HeroIteratorImpl.java: -------------------------------------------------------------------------------- 1 | package behavioral.Iterator.withoutgeneric; 2 | 3 | public class HeroIteratorImpl implements HeroIterator { 4 | 5 | Hero[] heroes; 6 | int cursor; 7 | int length; 8 | 9 | HeroIteratorImpl(Hero[] heroes){ 10 | this.heroes = heroes; 11 | cursor = 0; 12 | length = heroes.length; 13 | } 14 | 15 | @Override 16 | public boolean hasNext() { 17 | return cursor < heroes.length; 18 | } 19 | 20 | @Override 21 | public Hero next() { 22 | return heroes[cursor++]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/behavioral/Iterator/withoutgeneric/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.Iterator.withoutgeneric; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | HeroCollection heroCollection = new HeroCollection(5); 6 | 7 | heroCollection.addHero(new Hero("NTR Jr")); 8 | heroCollection.addHero(new Hero("Prabhas")); 9 | heroCollection.addHero(new Hero("Yash")); 10 | heroCollection.addHero(new Hero("Allu Arjun")); 11 | heroCollection.addHero(new Hero("Rishab Shetty")); 12 | 13 | HeroIterator iterator = heroCollection.iterator(); 14 | 15 | while (iterator.hasNext()){ 16 | System.out.println(iterator.next().getName()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/atmexample/Currency.java: -------------------------------------------------------------------------------- 1 | package behavioral.chainofresponsibility.atmexample; 2 | 3 | public class Currency { 4 | private final int amount; 5 | 6 | public Currency(int amount) { 7 | this.amount = amount; 8 | } 9 | 10 | public int getAmount() { 11 | return amount; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/atmexample/Dollar100Dispenser.java: -------------------------------------------------------------------------------- 1 | package behavioral.chainofresponsibility.atmexample; 2 | 3 | public class Dollar100Dispenser extends DollarDispenser { 4 | 5 | public Dollar100Dispenser(DollarDispenser dollarDispenser) { 6 | super(dollarDispenser); 7 | } 8 | 9 | @Override 10 | public void dispense(Currency cur) { 11 | if(cur.getAmount()>=100){ 12 | int num = cur.getAmount()/100; 13 | int remainder = cur.getAmount() % 100; 14 | System.out.println("Dispensing "+num+" 100$ note"); 15 | if(remainder !=0) dollarDispenser.dispense(new Currency(remainder)); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/atmexample/Dollar2000Dispenser.java: -------------------------------------------------------------------------------- 1 | package behavioral.chainofresponsibility.atmexample; 2 | 3 | public class Dollar2000Dispenser extends DollarDispenser { 4 | 5 | public Dollar2000Dispenser(DollarDispenser dollarDispenser) { 6 | super(dollarDispenser); 7 | } 8 | 9 | @Override 10 | public void dispense(Currency cur) { 11 | if(cur.getAmount()>=2000){ 12 | int num = cur.getAmount()/2000; 13 | int remainder = cur.getAmount() % 2000; 14 | System.out.println("Dispensing "+num+" 2000$ note"); 15 | if(remainder !=0) dollarDispenser.dispense(new Currency(remainder)); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/atmexample/Dollar500Dispenser.java: -------------------------------------------------------------------------------- 1 | package behavioral.chainofresponsibility.atmexample; 2 | 3 | public class Dollar500Dispenser extends DollarDispenser { 4 | 5 | public Dollar500Dispenser(DollarDispenser dollarDispenser) { 6 | super(dollarDispenser); 7 | } 8 | 9 | @Override 10 | public void dispense(Currency cur) { 11 | if(cur.getAmount()>=500){ 12 | int num = cur.getAmount()/500; 13 | int remainder = cur.getAmount() % 500; 14 | System.out.println("Dispensing "+num+" 500$ note"); 15 | if(remainder !=0) dollarDispenser.dispense(new Currency(remainder)); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/atmexample/DollarDispenser.java: -------------------------------------------------------------------------------- 1 | package behavioral.chainofresponsibility.atmexample; 2 | 3 | public abstract class DollarDispenser { 4 | public DollarDispenser dollarDispenser; 5 | 6 | public DollarDispenser(DollarDispenser dollarDispenser) { 7 | this.dollarDispenser = dollarDispenser; 8 | } 9 | 10 | public abstract void dispense(Currency cur); 11 | } 12 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/atmexample/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.chainofresponsibility.atmexample; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | DollarDispenser dollarDispenser = new ValidateDollarDispenser( 6 | new Dollar2000Dispenser(new Dollar500Dispenser(new Dollar100Dispenser(null))) 7 | ); 8 | 9 | dollarDispenser.dispense(new Currency(5600)); 10 | 11 | dollarDispenser.dispense(new Currency(5620)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/atmexample/ValidateDollarDispenser.java: -------------------------------------------------------------------------------- 1 | package behavioral.chainofresponsibility.atmexample; 2 | 3 | public class ValidateDollarDispenser extends DollarDispenser{ 4 | 5 | public ValidateDollarDispenser(DollarDispenser dollarDispenser) { 6 | super(dollarDispenser); 7 | } 8 | 9 | @Override 10 | public void dispense(Currency cur) { 11 | if(cur.getAmount()%100==0){ 12 | dollarDispenser.dispense(cur); 13 | } else { 14 | System.out.println("Please Enter Amount in 2000,500,100 denominations"); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/authexample/AuthenticationProcessor.java: -------------------------------------------------------------------------------- 1 | package behavioral.chainofresponsibility.authexample; 2 | 3 | public abstract class AuthenticationProcessor { 4 | public AuthenticationProcessor nextProcessor; 5 | 6 | public AuthenticationProcessor(AuthenticationProcessor nextProcessor) { 7 | this.nextProcessor = nextProcessor; 8 | } 9 | 10 | public abstract boolean isAuthorized(AuthenticationProcessor authProvider); 11 | } 12 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/authexample/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.chainofresponsibility.authexample; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | AuthenticationProcessor authenticationProcessor = new UserNamePasswordProcessor( 6 | new OAuthProcessor(null) 7 | ); 8 | 9 | System.out.println(authenticationProcessor.isAuthorized(new OAuthProcessor(null))); 10 | System.out.println(authenticationProcessor.isAuthorized(new UserNamePasswordProcessor(null))); 11 | System.out.println(authenticationProcessor.isAuthorized(new TokenBasedProcessor(null))); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/authexample/OAuthProcessor.java: -------------------------------------------------------------------------------- 1 | package behavioral.chainofresponsibility.authexample; 2 | 3 | public class OAuthProcessor extends AuthenticationProcessor{ 4 | 5 | public OAuthProcessor(AuthenticationProcessor authenticationProcessor){ 6 | super(authenticationProcessor); 7 | } 8 | 9 | @Override 10 | public boolean isAuthorized(AuthenticationProcessor authProvider) { 11 | if(authProvider instanceof OAuthProcessor) return true; 12 | else if(nextProcessor!=null) return nextProcessor.isAuthorized(authProvider); 13 | return false; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/authexample/TokenBasedProcessor.java: -------------------------------------------------------------------------------- 1 | package behavioral.chainofresponsibility.authexample; 2 | 3 | public class TokenBasedProcessor extends AuthenticationProcessor{ 4 | 5 | public TokenBasedProcessor(AuthenticationProcessor authenticationProcessor){ 6 | super(authenticationProcessor); 7 | } 8 | 9 | @Override 10 | public boolean isAuthorized(AuthenticationProcessor authProvider) { 11 | if(authProvider instanceof TokenBasedProcessor) return true; 12 | else if(nextProcessor!=null) return nextProcessor.isAuthorized(authProvider); 13 | return false; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/authexample/UserNamePasswordProcessor.java: -------------------------------------------------------------------------------- 1 | package behavioral.chainofresponsibility.authexample; 2 | 3 | public class UserNamePasswordProcessor extends AuthenticationProcessor { 4 | 5 | public UserNamePasswordProcessor(AuthenticationProcessor authenticationProcessor){ 6 | super(authenticationProcessor); 7 | } 8 | 9 | @Override 10 | public boolean isAuthorized(AuthenticationProcessor authProvider) { 11 | if(authProvider instanceof UserNamePasswordProcessor) return true; 12 | else if(nextProcessor!=null) return nextProcessor.isAuthorized(authProvider); 13 | return false; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/chain_of_responsibility.md: -------------------------------------------------------------------------------- 1 | Intent: 2 | --------- 3 | Chain of Responsibility is a behavioral design pattern that lets you pass requests along a chain of handlers. 4 | Upon receiving a request, each handler decides either to process the request or to pass it to the next handler 5 | in the chain 6 | 7 | the Chain of Responsibility relies on transforming particular behaviors into stand-alone objects called **handlers**. 8 | 9 | Advantages of Chain of Responsibility 10 | ------------------------------------ 11 | 1. Reduced coupling 12 | 2. Added flexibility in assigning responsibilities to objects 13 | 3. Receipt isn't guaranteed 14 | 15 | Disadvantages 16 | -------------- 17 | 1. Mostly, it can get broken easily: 18 | if a processor fails to call the next processor, the command gets dropped 19 | if a processor calls the wrong processor, it can lead to a cycle 20 | 2. It can create deep stack traces, which can affect performance 21 | 3. It can lead to duplicate code across processors, increasing maintenance 22 | 23 | 24 | ![cor.png](cor.png) 25 | 26 | RealWorld 27 | 1. DoFilter 28 | 2. Logger 29 | 30 | -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/cop.draw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/chainofresponsibility/cop.draw.png -------------------------------------------------------------------------------- /src/behavioral/chainofresponsibility/cor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/chainofresponsibility/cor.png -------------------------------------------------------------------------------- /src/behavioral/command/cartexample/FoodDeliveryException.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.cartexample; 2 | 3 | 4 | 5 | public class FoodDeliveryException extends RuntimeException { 6 | private String message; 7 | 8 | public FoodDeliveryException(String message) { 9 | this.message = message; 10 | } 11 | 12 | @Override 13 | public String getMessage() { 14 | return message; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/behavioral/command/cartexample/FoodMenuService.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.cartexample; 2 | 3 | 4 | import behavioral.command.cartexample.data.FoodMenuData; 5 | import behavioral.command.cartexample.model.FoodMenu; 6 | 7 | public class FoodMenuService { 8 | private FoodMenuData foodMenuData; 9 | 10 | 11 | public FoodMenuService(FoodMenuData foodMenuData) { 12 | this.foodMenuData = foodMenuData; 13 | } 14 | 15 | public FoodMenu getMenuById(final String menuId) { 16 | if (!foodMenuData.getFoodMenuById().containsKey(menuId)) { 17 | throw new FoodDeliveryException("Food Menu not exists"); 18 | } 19 | return foodMenuData.getFoodMenuById().get(menuId); 20 | } 21 | 22 | public FoodMenu getMenuByRestaurantId(final String restaurantId) { 23 | if (!foodMenuData.getFoodMenuIdByRestaurantId().containsKey(restaurantId)) { 24 | throw new FoodDeliveryException("No Data"); 25 | } 26 | return getMenuById(foodMenuData.getFoodMenuIdByRestaurantId().get(restaurantId)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/behavioral/command/cartexample/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.cartexample; 2 | 3 | import behavioral.command.cartexample.data.CartData; 4 | import behavioral.command.cartexample.data.FoodMenuData; 5 | import behavioral.command.cartexample.pattern.AddCartCommandExecutor; 6 | import behavioral.command.cartexample.pattern.CartCommandExecutor; 7 | import behavioral.command.cartexample.pattern.CartCommandType; 8 | import behavioral.command.cartexample.pattern.RemoveCartCommandExecutor; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | public class Main { 15 | public static void main(String[] args) throws Exception { 16 | 17 | CartData cartData = new CartData(); 18 | FoodMenuService foodMenuService = new FoodMenuService(new FoodMenuData()); 19 | 20 | List cartCommandExecutorList = Arrays.asList(new AddCartCommandExecutor(foodMenuService, cartData), 21 | new RemoveCartCommandExecutor(cartData)); 22 | 23 | CartCommandType cartCommandType = CartCommandType.ADD_ITEM; 24 | for (CartCommandExecutor cartCommandExecutor : cartCommandExecutorList) { 25 | 26 | if (cartCommandExecutor.isApplicable(cartCommandType)) { 27 | cartCommandExecutor.execute("lava", "Bawaachi", "Biryani"); 28 | } 29 | 30 | if (cartCommandExecutor.isApplicable(CartCommandType.REMOVE_ITEM)) { 31 | cartCommandExecutor.execute("lava", "Bawaachi", "Biryani"); 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/behavioral/command/cartexample/data/CartData.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.cartexample.data; 2 | 3 | 4 | import behavioral.command.cartexample.FoodDeliveryException; 5 | 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | 11 | public class CartData { 12 | private Map>> userToRestaurantIdToMenuItemIds = new HashMap<>(); 13 | 14 | public List getMenuItemIds(final String userId, final String restaurantId) { 15 | Map> restaurantIdToMenuItemIds = getRestaurantIdToMenuItemIds(userId); 16 | if (!restaurantIdToMenuItemIds.containsKey(restaurantId)) { 17 | throw new FoodDeliveryException("Cart is empty for this restaurant"); 18 | } 19 | return restaurantIdToMenuItemIds.get(restaurantId); 20 | } 21 | 22 | public Map> getRestaurantIdToMenuItemIds(final String userId) { 23 | return userToRestaurantIdToMenuItemIds.getOrDefault(userId, new HashMap<>()); 24 | } 25 | 26 | public Map>> getUserToRestaurantIdToMenuItemIds() { 27 | return userToRestaurantIdToMenuItemIds; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/behavioral/command/cartexample/data/FoodMenuData.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.cartexample.data; 2 | 3 | import behavioral.command.cartexample.model.FoodMenu; 4 | import behavioral.command.cartexample.model.MenuItem; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | public class FoodMenuData { 10 | private Map foodMenuById = new HashMap<>(); 11 | private Map foodMenuIdByRestaurantId = new HashMap<>(); 12 | private Map menuItemById = new HashMap<>(); 13 | 14 | 15 | public Map getFoodMenuById() { 16 | return foodMenuById; 17 | } 18 | 19 | public Map getFoodMenuIdByRestaurantId() { 20 | return foodMenuIdByRestaurantId; 21 | } 22 | 23 | public Map getMenuItemById() { 24 | return menuItemById; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/behavioral/command/cartexample/model/FoodMenu.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.cartexample.model; 2 | 3 | 4 | import java.util.List; 5 | 6 | 7 | public class FoodMenu { 8 | private String id; 9 | private List restaurantIds; 10 | private List menuItemList; 11 | 12 | public String getId() { 13 | return id; 14 | } 15 | 16 | public List getRestaurantIds() { 17 | return restaurantIds; 18 | } 19 | 20 | public List getMenuItemList() { 21 | return menuItemList; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/behavioral/command/cartexample/model/MealType.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.cartexample.model; 2 | 3 | public enum MealType { 4 | BREAKFAST, 5 | BRUNCH, 6 | ELEVENSES, 7 | LUNCH, 8 | DINNER, 9 | SUPPER, 10 | AFTERNOON_TEA, 11 | HIGH_TEA 12 | } 13 | -------------------------------------------------------------------------------- /src/behavioral/command/cartexample/model/MenuItem.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.cartexample.model; 2 | 3 | 4 | public class MenuItem { 5 | private String id; 6 | private String itemName; 7 | private MealType mealType; 8 | private double price; 9 | 10 | public String getId() { 11 | return id; 12 | } 13 | 14 | public String getItemName() { 15 | return itemName; 16 | } 17 | 18 | public MealType getMealType() { 19 | return mealType; 20 | } 21 | 22 | public double getPrice() { 23 | return price; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/behavioral/command/cartexample/pattern/AddCartCommandExecutor.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.cartexample.pattern; 2 | 3 | import behavioral.command.cartexample.data.CartData; 4 | import behavioral.command.cartexample.FoodMenuService; 5 | import behavioral.command.cartexample.model.FoodMenu; 6 | 7 | import java.util.ArrayList; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | 13 | public class AddCartCommandExecutor extends CartCommandExecutor { 14 | private FoodMenuService foodMenuService; 15 | private CartData cartData; 16 | 17 | public AddCartCommandExecutor(FoodMenuService foodMenuService, CartData cartData) { 18 | this.foodMenuService = foodMenuService; 19 | this.cartData = cartData; 20 | } 21 | 22 | @Override 23 | public boolean isValid(final String userId, final String restaurantId, final String itemId) { 24 | FoodMenu foodMenu = foodMenuService.getMenuByRestaurantId(restaurantId); 25 | return foodMenu.getMenuItemList().stream() 26 | .anyMatch(menuItem -> menuItem.getId().equals(itemId)); 27 | } 28 | 29 | @Override 30 | public void executeCommand(final String userId, final String restaurantId, final String itemId) { 31 | Map> restaurantIdToMenuItemIds = 32 | cartData.getUserToRestaurantIdToMenuItemIds().getOrDefault(userId, new HashMap<>()); 33 | List menuItemIds = restaurantIdToMenuItemIds.getOrDefault(restaurantId, new ArrayList<>()); 34 | menuItemIds.add(itemId); 35 | restaurantIdToMenuItemIds.put(restaurantId, menuItemIds); 36 | cartData.getUserToRestaurantIdToMenuItemIds().put(userId, restaurantIdToMenuItemIds); 37 | } 38 | 39 | @Override 40 | public boolean isApplicable(CartCommandType cartCommandType) { 41 | return cartCommandType == CartCommandType.ADD_ITEM; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/behavioral/command/cartexample/pattern/CartCommandExecutor.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.cartexample.pattern; 2 | 3 | import behavioral.command.cartexample.FoodDeliveryException; 4 | 5 | public abstract class CartCommandExecutor { 6 | public void execute(final String userId,final String restaurantId, final String itemId) throws Exception { 7 | if (!isValid(userId, restaurantId, itemId)) { 8 | throw new FoodDeliveryException("menu item not found"); 9 | } 10 | executeCommand(userId, restaurantId, itemId); 11 | } 12 | 13 | public abstract boolean isValid(final String userId, final String restaurantId, final String itemId); 14 | 15 | public abstract void executeCommand(final String userId, final String restaurantId, final String itemId); 16 | 17 | public abstract boolean isApplicable(final CartCommandType cartCommandType); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/behavioral/command/cartexample/pattern/CartCommandType.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.cartexample.pattern; 2 | 3 | public enum CartCommandType { 4 | ADD_ITEM, 5 | REMOVE_ITEM, 6 | CLEAR_CART 7 | } 8 | -------------------------------------------------------------------------------- /src/behavioral/command/cartexample/pattern/RemoveCartCommandExecutor.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.cartexample.pattern; 2 | 3 | 4 | import behavioral.command.cartexample.data.CartData; 5 | 6 | import java.util.List; 7 | 8 | 9 | public class RemoveCartCommandExecutor extends CartCommandExecutor { 10 | private CartData cartData; 11 | 12 | public RemoveCartCommandExecutor(CartData cartData) { 13 | this.cartData = cartData; 14 | } 15 | 16 | @Override 17 | public boolean isValid(final String userId, final String restaurantId, final String itemId) { 18 | return cartData.getMenuItemIds(userId, restaurantId).contains(itemId); 19 | } 20 | 21 | @Override 22 | public void executeCommand(final String userId, final String restaurantId, final String itemId) { 23 | List menuItemIds = cartData.getMenuItemIds(userId, restaurantId); 24 | menuItemIds.remove(itemId); 25 | } 26 | 27 | @Override 28 | public boolean isApplicable(CartCommandType cartCommandType) { 29 | return cartCommandType == CartCommandType.REMOVE_ITEM; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/behavioral/command/command.md: -------------------------------------------------------------------------------- 1 | **Intent** 2 | - 3 | *Encapsulate a request as an object, thereby letting you parameterize clients with 4 | different requests, queue or log requests, and support undoable operations.* 5 | 6 | Also, Known As - `Action, Transaction` 7 | 8 | ![img.png](command.png) 9 | 10 | ![Iterator](command_sketch.png) 11 | **Applicability** 12 | - 13 | 14 | Use the Command pattern when you want to 15 | 1. parameterize objects by an action to perform, as MenuItem objects. 16 | 2. specify, queue, and execute requests at different times. A Command object 17 | can have a lifetime independent of the original request. If the receiver of a 18 | request can be represented in an address space-independent way, then you 19 | can transfer a command object for the request to a different process and fulfill 20 | the request there. 21 | 3. support undo. TheCommand's Execute operation can store state for reversing its effects in the command itself. The Command interface must have an 22 | added un-execute operation that reverses the effects of a previous call to execute. Executed commands are stored in a history list. Unlimited-level undo 23 | and redo is achieved by traversing this list backwards and forwards calling 24 | un-execute and Execute,respectively. 25 | 4. support logging changes so that they can be reapplied in case of a system 26 | crash. By augmenting the Command interface with load and store operations, you can keep a persistent log of changes. Recovering from a crash 27 | involves reloading logged commands from disk and re-executing them with 28 | the Execute operation. 29 | 5. structure a system around high-level operations built on primitives operations. Such a structure is common in information systems that support transactions. A transaction encapsulates a set of changes to data. The Command 30 | pattern offers a way to model transactions. Commands have a common interface, letting you invoke all transactions the same way. The pattern also 31 | makes it easy to extend the system with new transactions. 32 | -------------------------------------------------------------------------------- /src/behavioral/command/command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/command/command.png -------------------------------------------------------------------------------- /src/behavioral/command/command_sketch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/command/command_sketch.png -------------------------------------------------------------------------------- /src/behavioral/command/remoteexample/Command.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.remoteexample; 2 | 3 | public interface Command { 4 | void execute(); 5 | } 6 | -------------------------------------------------------------------------------- /src/behavioral/command/remoteexample/Garage.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.remoteexample; 2 | 3 | public class Garage { 4 | 5 | public void opened(){ 6 | System.out.println("Door Opened"); 7 | } 8 | 9 | public void closed(){ 10 | System.out.println("Door Closed"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/behavioral/command/remoteexample/GarageDoorClosedCommand.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.remoteexample; 2 | 3 | public class GarageDoorClosedCommand implements Command { 4 | 5 | Garage garage; 6 | 7 | public GarageDoorClosedCommand(Garage garage){ 8 | this.garage = garage; 9 | } 10 | 11 | @Override 12 | public void execute() { 13 | garage.closed(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/behavioral/command/remoteexample/GarageDoorOpenCommand.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.remoteexample; 2 | 3 | public class GarageDoorOpenCommand implements Command { 4 | 5 | Garage garage; 6 | 7 | public GarageDoorOpenCommand(Garage garage){ 8 | this.garage = garage; 9 | } 10 | 11 | @Override 12 | public void execute() { 13 | garage.opened(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/behavioral/command/remoteexample/Light.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.remoteexample; 2 | 3 | public class Light { 4 | 5 | public void on(){ 6 | System.out.println("Light On"); 7 | } 8 | public void off(){ 9 | System.out.println("Light Off"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/behavioral/command/remoteexample/LightOffCommand.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.remoteexample; 2 | 3 | public class LightOffCommand implements Command { 4 | Light light; 5 | 6 | public LightOffCommand(Light light){ 7 | this.light = light; 8 | } 9 | 10 | @Override 11 | public void execute() { 12 | light.off(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/behavioral/command/remoteexample/LightOnCommand.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.remoteexample; 2 | 3 | public class LightOnCommand implements Command { 4 | Light light; 5 | 6 | public LightOnCommand(Light light){ 7 | this.light = light; 8 | } 9 | 10 | @Override 11 | public void execute() { 12 | light.on(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/behavioral/command/remoteexample/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.remoteexample; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | RemoteControl remoteControl = new RemoteControl(); 6 | 7 | 8 | remoteControl.setCommand(0,new LightOnCommand(new Light()),SlotType.ON); 9 | remoteControl.setCommand(0,new LightOffCommand(new Light()),SlotType.OFF); 10 | remoteControl.setCommand(1, new GarageDoorOpenCommand(new Garage()), SlotType.ON); 11 | remoteControl.setCommand(1, new GarageDoorClosedCommand(new Garage()), SlotType.OFF); 12 | 13 | 14 | remoteControl.buttonPressed(0, SlotType.ON); 15 | remoteControl.buttonPressed(1, SlotType.ON); 16 | 17 | remoteControl.offButtonPressed(0); 18 | remoteControl.offButtonPressed(1); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/behavioral/command/remoteexample/RemoteControl.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.remoteexample; 2 | 3 | public class RemoteControl { 4 | Command[] onSlots; 5 | Command[] offSlots; 6 | public RemoteControl(){ 7 | onSlots = new Command[2]; 8 | offSlots = new Command[2]; 9 | } 10 | 11 | public void setCommand(int slot, Command command, SlotType slotType){ 12 | if(slotType.equals(SlotType.ON))this.onSlots[slot] = command; 13 | else if(slotType.equals(SlotType.OFF)) this.offSlots[slot] = command; 14 | } 15 | public void buttonPressed(int slot, SlotType slotType){ 16 | if(slotType.equals(SlotType.ON))this.onSlots[slot].execute(); 17 | else if(slotType.equals(SlotType.OFF)) this.offSlots[slot].execute(); 18 | } 19 | 20 | public void onButtonPressed(int slot){ 21 | this.onSlots[slot].execute(); 22 | } 23 | 24 | public void offButtonPressed(int slot){ 25 | this.offSlots[slot].execute(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/behavioral/command/remoteexample/SlotType.java: -------------------------------------------------------------------------------- 1 | package behavioral.command.remoteexample; 2 | 3 | public enum SlotType { 4 | ON, 5 | OFF; 6 | } 7 | -------------------------------------------------------------------------------- /src/behavioral/mediator/ChatMediator.java: -------------------------------------------------------------------------------- 1 | package behavioral.mediator; 2 | 3 | public interface ChatMediator { 4 | public void sendMessage(String msg, User user); 5 | 6 | void addUser(User user); 7 | } 8 | -------------------------------------------------------------------------------- /src/behavioral/mediator/ChatMediatorImpl.java: -------------------------------------------------------------------------------- 1 | package behavioral.mediator; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | class ChatMediatorImpl implements ChatMediator { 7 | 8 | private final List users; 9 | 10 | ChatMediatorImpl(){ 11 | this.users=new ArrayList<>(); 12 | } 13 | 14 | @Override 15 | public void sendMessage(String msg, User user) { 16 | for(User u : this.users){ 17 | if(u != user){ 18 | u.receive(msg); 19 | } 20 | } 21 | } 22 | 23 | @Override 24 | public void addUser(User user) { 25 | users.add(user); 26 | } 27 | } -------------------------------------------------------------------------------- /src/behavioral/mediator/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.mediator; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | 6 | ChatMediator mediator = new ChatMediatorImpl(); 7 | 8 | 9 | User user1 = new UserImpl(mediator, "Rama Rao"); 10 | User user2 = new UserImpl(mediator, "Rajmouli"); 11 | User user3 = new UserImpl(mediator, "Ram Charan"); 12 | User user4 = new UserImpl(mediator, "Kerravani"); 13 | 14 | mediator.addUser(user1); 15 | mediator.addUser(user2); 16 | mediator.addUser(user3); 17 | mediator.addUser(user4); 18 | 19 | user1.send("Hey We won Golden Globe Award For Nattu Nattu"); 20 | System.out.println(); 21 | user2.send("Hurray Congrats Keeravani"); 22 | System.out.println(); 23 | user4.send("Thank you"); 24 | System.out.println(); 25 | user3.send("Fingers Crossed for Future Awards"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/behavioral/mediator/User.java: -------------------------------------------------------------------------------- 1 | package behavioral.mediator; 2 | 3 | public abstract class User { 4 | protected ChatMediator mediator; 5 | protected String name; 6 | 7 | public User(ChatMediator med, String name){ 8 | this.mediator=med; 9 | this.name=name; 10 | } 11 | 12 | public abstract void send(String msg); 13 | 14 | public abstract void receive(String msg); 15 | } 16 | -------------------------------------------------------------------------------- /src/behavioral/mediator/UserImpl.java: -------------------------------------------------------------------------------- 1 | package behavioral.mediator; 2 | 3 | public class UserImpl extends User{ 4 | 5 | public UserImpl(ChatMediator med, String name) { 6 | super(med, name); 7 | } 8 | 9 | @Override 10 | public void send(String msg) { 11 | System.out.println(this.name+": Sending Message="+msg); 12 | mediator.sendMessage(msg, this); 13 | } 14 | 15 | @Override 16 | public void receive(String msg) { 17 | System.out.println(this.name+": Received Message:"+msg); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/behavioral/mediator/mediator.md: -------------------------------------------------------------------------------- 1 | Intent 2 | ---------- 3 | Define an object that encapsulates how a set of objects interact. Mediator promotes 4 | loose coupling by keeping objects from referring to each other explicitly, and it 5 | lets you vary their interaction independently. 6 | 7 | ![mediator.png](mediator.png) 8 | 9 | ![mediator](mediator_sketch.png) 10 | **Example:** 11 | --------- 12 | Dialog Box 13 | ----------- 14 | 1. Often there are dependencies between the widgets in the dialog. For example, 15 | a button gets disabled when a certain entry field is empty. Selecting an entry 16 | in a list of choices called a list box might change the contents of an entry field. 17 | Conversely, typing text into the entry field might automatically select one or more 18 | corresponding entries in the list box. Once text appears in the entry field, other 19 | buttons may become enabled that let the user do something with the text,such as 20 | changing or deleting the thing to which it refers. 21 | 22 | 2. Different dialog boxes will have different dependencies between widgets. So even 23 | though dialogs display the same kinds of widgets, they can't simply reuse stock 24 | widget classes; they have to be customized to reflect dialog-specific dependencies. 25 | Customizing them individually by subclassing will be tedious, since many classes 26 | are involved 27 | 28 | 3. You can avoid these problems by encapsulating collective behavior in a separate 29 | mediator object 30 | 31 | ------------------------------------------------------------------------ 32 | A **mediator** is responsible for controlling and coordinating the 33 | _interactions_ of a group of objects. The mediator serves as an intermediary that 34 | keeps objects in the group from referring to each other explicitly. The objects only 35 | know the mediator, thereby _reducing the number of interconnections_. 36 | 37 | **_Use of Mediator Pattern_** 38 | 39 | The Mediator Pattern is a good choice if we have to deal with a set of objects that are tightly coupled and hard to maintain. 40 | This way we can reduce the dependencies between objects and decrease the overall complexity. 41 | 42 | Additionally, by using the mediator object, we extract the communication logic to the single component, 43 | therefore we follow the _Single Responsibility Principle_. Furthermore, we can introduce new mediators with 44 | no need to change the remaining parts of the system. Hence, we follow the _Open-Closed Principle_. 45 | 46 | ****Consequences**** 47 | 48 | 1. It limits subclassing 49 | 2. decouples colleagues 50 | 3. simplifies object protocols 51 | 4. abstracts how objects cooperate 52 | 5. centralizes control 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/behavioral/mediator/mediator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/mediator/mediator.png -------------------------------------------------------------------------------- /src/behavioral/mediator/mediator_sketch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/mediator/mediator_sketch.png -------------------------------------------------------------------------------- /src/behavioral/memento/example1/AccessTime.java: -------------------------------------------------------------------------------- 1 | package behavioral.memento.example1; 2 | 3 | // Originator - is the object whose state we want to save and restore 4 | public class AccessTime { 5 | private String time; 6 | 7 | public void setTime(String time) { 8 | System.out.println("Setting time to " + time); 9 | this.time = time; 10 | } 11 | 12 | // Originators : methods to create and consume the Memento object, making the AccessTime our Originator 13 | public TimeState save() { 14 | System.out.println("Saving time to Memento"); 15 | return new TimeState(time); 16 | } 17 | 18 | public void restore(TimeState timeState) { 19 | time = timeState.getSavedTime(); 20 | System.out.println("Time restored from Memento: " + time); 21 | } 22 | 23 | public String getTime(){ 24 | return time; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/behavioral/memento/example1/Checkpoint.java: -------------------------------------------------------------------------------- 1 | package behavioral.memento.example1; 2 | 3 | // Caretaker - responsible for saving and restoring the state of the Originator. 4 | public class Checkpoint { 5 | AccessTime accessTime; 6 | TimeState timeState; 7 | 8 | public Checkpoint(AccessTime accessTime){ 9 | this.accessTime = accessTime; 10 | } 11 | 12 | // Care Takers 13 | public void saveCheckpoint() { 14 | timeState = accessTime.save(); 15 | } 16 | 17 | public void rollbackToLastCheckPoint() { 18 | accessTime.restore(timeState); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/behavioral/memento/example1/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.memento.example1; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | 6 | AccessTime accessTime = new AccessTime(); 7 | 8 | Checkpoint checkpoint = new Checkpoint(accessTime); 9 | 10 | accessTime.setTime("11AM"); 11 | 12 | checkpoint.saveCheckpoint(); 13 | 14 | accessTime.setTime("12PM"); 15 | 16 | System.out.println(accessTime.getTime()); 17 | 18 | checkpoint.rollbackToLastCheckPoint(); 19 | 20 | System.out.println(accessTime.getTime()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/behavioral/memento/example1/TimeState.java: -------------------------------------------------------------------------------- 1 | package behavioral.memento.example1; 2 | 3 | // Memento - which is a special object that contains the state of the Originator. 4 | public class TimeState { 5 | private final String lastTimeSaved; 6 | 7 | public TimeState(String timeToSave) 8 | { 9 | lastTimeSaved = timeToSave; 10 | } 11 | 12 | public String getSavedTime() 13 | { 14 | return lastTimeSaved; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/behavioral/memento/example2/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.memento.example2; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | // Originator 6 | TextWindow textWindow = new TextWindow(); 7 | 8 | // Care taker 9 | TextEditor textEditor = new TextEditor(textWindow); 10 | 11 | textWindow.setState("Welcome to My Channel"); 12 | 13 | textEditor.hitSave(); 14 | 15 | textWindow.setState(" Please Subscribe"); 16 | 17 | System.out.println(textWindow.getState()+" "); 18 | 19 | textEditor.hitUndo(); 20 | 21 | System.out.println(textWindow.getState()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/behavioral/memento/example2/TextEditor.java: -------------------------------------------------------------------------------- 1 | package behavioral.memento.example2; 2 | 3 | // Caretaker 4 | public class TextEditor { 5 | 6 | 7 | private TextWindow textWindow; 8 | private TextWindowMemento savedTextWindow; 9 | 10 | public TextEditor(TextWindow textWindow) { 11 | this.textWindow = textWindow; 12 | } 13 | 14 | // Care Takers (As the Caretaker, it will hold the state of the Originator and ask to restore it when needed) 15 | 16 | public void hitSave() { 17 | savedTextWindow = textWindow.saveStateToMemento(); 18 | } 19 | 20 | public void hitUndo() { 21 | textWindow.restoreStateFromMemento(savedTextWindow); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/behavioral/memento/example2/TextWindow.java: -------------------------------------------------------------------------------- 1 | package behavioral.memento.example2; 2 | 3 | // Originator 4 | public class TextWindow { 5 | private StringBuilder state; 6 | 7 | public TextWindow() { 8 | this.state = new StringBuilder(); 9 | } 10 | 11 | public void setState(String text) { 12 | state.append(text); 13 | } 14 | 15 | public TextWindowMemento saveStateToMemento() { 16 | return new TextWindowMemento(state.toString()); 17 | } 18 | 19 | public void restoreStateFromMemento(TextWindowMemento save) { 20 | state = new StringBuilder(save.getState()); 21 | } 22 | 23 | public StringBuilder getState() { 24 | return state; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/behavioral/memento/example2/TextWindowMemento.java: -------------------------------------------------------------------------------- 1 | package behavioral.memento.example2; 2 | 3 | // Memento 4 | public class TextWindowMemento { 5 | private final String state; 6 | 7 | public TextWindowMemento(String state) { 8 | this.state = state; 9 | } 10 | 11 | public String getState() { 12 | return state; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/behavioral/memento/memento.md: -------------------------------------------------------------------------------- 1 | Intent 2 | ----------- 3 | Without violating encapsulation, capture and externalize an object's internal state 4 | so that the object can be restored to this state later. 5 | 6 | Motivation: 7 | ----------- 8 | Sometimes it's necessary to record the internal state of an object. This is required 9 | when implementing checkpoints and undo mechanisms that let users back outof 10 | tentative operations or recover from errors. You must save state information somewhere so that you can restore objects to their previous states.But objects normally 11 | encapsulate some or all of their state, making it inaccessible to other objects and 12 | impossible to save externally. Exposing this state would violate encapsulation, 13 | which can compromise the application's reliability and extensibility 14 | 15 | A memento is an object that stores a _snapshot_ of the internal state of another object—the memento's 16 | originator. The undo mechanism will request a memento from the originator when it needs to checkpoint 17 | the originator's state. The originator initializes the memento with information that characterizes its 18 | current state.Only the originator can store and retrieve information from the memento. 19 | the memento is "opaque" to other objects 20 | 21 | **Class Diagram** 22 | 23 | ![memento.png](memento.png) 24 | 25 | Example: 26 | 27 | ![Memento](memento_sketch.png) 28 | Practically, the object whose state needs to be saved is called an **Originator**. 29 | The **Caretaker** is the object triggering the save and restore of the state, which is called the **Memento**. 30 | 31 | The Memento object should expose as little information as possible to the Caretaker. 32 | This is to ensure that we don't expose the internal state of the Originator to the outside world, as it would break encapsulation principles. 33 | However, the Originator should access enough information in order to restore to the original state 34 | 35 | As we can see, the Originator can produce and consume a Memento. Meanwhile, the Caretaker only keeps the state before restoring it. 36 | The internal representation of the Originator is kept hidden from the external world. 37 | 38 | **When to Use Memento Design Pattern?** 39 | 40 | Typically, the Memento Design Pattern will be used in situations where some actions are undoable, 41 | therefore requiring to rollback to a previous state. However, if the state of the Originator is heavy, 42 | using the Memento Design Pattern can lead to an expensive creation process and increased use of memory. -------------------------------------------------------------------------------- /src/behavioral/memento/memento.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/memento/memento.png -------------------------------------------------------------------------------- /src/behavioral/memento/memento_sketch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/memento/memento_sketch.png -------------------------------------------------------------------------------- /src/behavioral/observer/observer.md: -------------------------------------------------------------------------------- 1 | Intent 2 | --------- 3 | Define a one-to-many dependency between objects so that when one object 4 | changes state, all its dependents are notified and updated automatically. 5 | 6 | Also, Known As 7 | ------------- 8 | Dependents, Publish-Subscribe 9 | 10 | It specifies communication between objects: observable and observers. 11 | An **observable** is an object which notifies **observers** about the changes in its state. 12 | 13 | ![observer.png](observer.png) 14 | 15 | Example: 16 | - 17 | For example, a news agency can notify channels when it receives news. 18 | Receiving news is what changes the state of the news agency, and it causes the channels to be notified. -------------------------------------------------------------------------------- /src/behavioral/observer/observer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/observer/observer.png -------------------------------------------------------------------------------- /src/behavioral/observer/withlibraray/Driver.java: -------------------------------------------------------------------------------- 1 | package behavioral.observer.withlibraray; 2 | 3 | import java.util.Observer; 4 | 5 | public class Driver { 6 | public static void main(String[] args) { 7 | Observer newsSubscriber = new NewsSubscriber(); 8 | Observer socialMediaSubscriber = new SocialMediaSubscriber(); 9 | 10 | Producer producer = new Producer(); 11 | producer.addObserver(newsSubscriber); 12 | producer.addObserver(socialMediaSubscriber); 13 | 14 | 15 | producer.setNews("India Declared No Tax For Engineers"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/behavioral/observer/withlibraray/NewsSubscriber.java: -------------------------------------------------------------------------------- 1 | package behavioral.observer.withlibraray; 2 | 3 | import java.util.Observable; 4 | import java.util.Observer; 5 | 6 | public class NewsSubscriber implements Observer { 7 | private String news; 8 | 9 | public void display(){ 10 | System.out.println("News "+news); 11 | } 12 | 13 | @Override 14 | public void update(Observable o, Object news) { 15 | this.news = ((String) news); 16 | display(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/behavioral/observer/withlibraray/Producer.java: -------------------------------------------------------------------------------- 1 | package behavioral.observer.withlibraray; 2 | 3 | import java.util.Observable; 4 | 5 | public class Producer extends Observable { 6 | private String news; 7 | 8 | public void setNews(String news) { 9 | this.news = news; 10 | setChanged(); 11 | notifyObservers(news); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/behavioral/observer/withlibraray/SocialMediaSubscriber.java: -------------------------------------------------------------------------------- 1 | package behavioral.observer.withlibraray; 2 | 3 | 4 | 5 | import java.util.Observable; 6 | import java.util.Observer; 7 | 8 | public class SocialMediaSubscriber implements Observer { 9 | private String news; 10 | 11 | public void display(){ 12 | System.out.println("News "+news); 13 | } 14 | 15 | @Override 16 | public void update(Observable o, Object news) { 17 | this.news = ((String) news); 18 | display(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/behavioral/observer/withoutlibrary/Driver.java: -------------------------------------------------------------------------------- 1 | package behavioral.observer.withoutlibrary; 2 | 3 | public class Driver { 4 | public static void main(String[] args) { 5 | Subscriber subscriber1 = new NewsSubscriber(); 6 | Subscriber subscriber2 = new SocialMediaSubscriber(); 7 | 8 | Producer producer = new Producer(); 9 | producer.addObserver(subscriber1); 10 | producer.addObserver(subscriber2); 11 | 12 | 13 | producer.setNews("India Declared No Tax For Engineers"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/behavioral/observer/withoutlibrary/NewsSubscriber.java: -------------------------------------------------------------------------------- 1 | package behavioral.observer.withoutlibrary; 2 | 3 | public class NewsSubscriber implements Subscriber{ 4 | private String news; 5 | @Override 6 | public void update(String news) { 7 | this.news = news; 8 | display(); 9 | } 10 | 11 | public void display(){ 12 | System.out.println("News "+news); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/behavioral/observer/withoutlibrary/Producer.java: -------------------------------------------------------------------------------- 1 | package behavioral.observer.withoutlibrary; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Producer { 7 | private String news; 8 | private List channels = new ArrayList<>(); 9 | 10 | public void addObserver(Subscriber subscriber) { 11 | this.channels.add(subscriber); 12 | } 13 | 14 | public void removeObserver(Subscriber subscriber) { 15 | this.channels.remove(subscriber); 16 | } 17 | 18 | public void setNews(String news) { 19 | this.news = news; 20 | for (Subscriber subscriber : this.channels) { 21 | subscriber.update(this.news); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/behavioral/observer/withoutlibrary/SocialMediaSubscriber.java: -------------------------------------------------------------------------------- 1 | package behavioral.observer.withoutlibrary; 2 | 3 | public class SocialMediaSubscriber implements Subscriber{ 4 | private String news; 5 | @Override 6 | public void update(String news) { 7 | this.news = news; 8 | display(); 9 | } 10 | 11 | public void display(){ 12 | System.out.println("Social Media: "+news); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/behavioral/observer/withoutlibrary/Subscriber.java: -------------------------------------------------------------------------------- 1 | package behavioral.observer.withoutlibrary; 2 | 3 | public interface Subscriber { 4 | void update(String o); 5 | } 6 | -------------------------------------------------------------------------------- /src/behavioral/state/DeliveredState.java: -------------------------------------------------------------------------------- 1 | package behavioral.state; 2 | 3 | public class DeliveredState implements PackageState { 4 | 5 | @Override 6 | public void next(Package pkg) { 7 | pkg.setState(new ReceivedState()); 8 | } 9 | 10 | @Override 11 | public void prev(Package pkg) { 12 | pkg.setState(new OrderedState()); 13 | } 14 | 15 | @Override 16 | public void printStatus() { 17 | System.out.println("Package delivered to post office, not received yet."); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/behavioral/state/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.state; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | Package pkg = new Package(); 6 | // pkg.setState(new OrderedState()); 7 | pkg.printStatus(); 8 | pkg.nextState(); 9 | pkg.printStatus(); 10 | pkg.nextState(); 11 | pkg.printStatus(); 12 | pkg.nextState(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/behavioral/state/OrderedState.java: -------------------------------------------------------------------------------- 1 | package behavioral.state; 2 | 3 | public class OrderedState implements PackageState { 4 | 5 | @Override 6 | public void next(Package pkg) { 7 | pkg.setState(new DeliveredState()); 8 | } 9 | 10 | @Override 11 | public void prev(Package pkg) { 12 | System.out.println("The package is in its root state."); 13 | } 14 | 15 | @Override 16 | public void printStatus() { 17 | System.out.println("Package ordered, not delivered to the office yet."); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/behavioral/state/Package.java: -------------------------------------------------------------------------------- 1 | package behavioral.state; 2 | 3 | public class Package { 4 | 5 | private PackageState state; 6 | 7 | public Package() { 8 | state = new OrderedState(); 9 | } 10 | 11 | public PackageState getState() { 12 | return state; 13 | } 14 | 15 | public void setState(PackageState state) { 16 | this.state = state; 17 | } 18 | 19 | public void previousState() { 20 | state.prev(this); 21 | } 22 | 23 | public void nextState() { 24 | state.next(this); 25 | } 26 | 27 | public void printStatus() { 28 | state.printStatus(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/behavioral/state/PackageState.java: -------------------------------------------------------------------------------- 1 | package behavioral.state; 2 | 3 | public interface PackageState { 4 | void next(Package pkg); 5 | void prev(Package pkg); 6 | void printStatus(); 7 | } 8 | -------------------------------------------------------------------------------- /src/behavioral/state/ReceivedState.java: -------------------------------------------------------------------------------- 1 | package behavioral.state; 2 | 3 | public class ReceivedState implements PackageState { 4 | 5 | @Override 6 | public void next(Package pkg) { 7 | System.out.println("This package is already received by a client."); 8 | } 9 | 10 | @Override 11 | public void prev(Package pkg) { 12 | pkg.setState(new DeliveredState()); 13 | } 14 | 15 | @Override 16 | public void printStatus() { 17 | System.out.println("Recieved"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/behavioral/state/state.md: -------------------------------------------------------------------------------- 1 | Intent 2 | -------- 3 | Allow an object to alter its behavior when its internal state changes. The object 4 | will appear to change its class 5 | 6 | idea = "allow the object for changing its behavior without changing its class" 7 | 8 | UML Diagram 9 | ![state.png](state.png) 10 | 11 | In the UML diagram, we see that **Context** class has an associated State which is going to change during program execution. 12 | 13 | Our context is going to delegate the behavior to the state implementation. In other words, all incoming requests will be handled by the concrete implementation of the state. 14 | 15 | We see that logic is separated and adding new states is simple – it comes down to adding another State implementation if needed 16 | 17 | Example 18 | 1. During Food Delivery Possible States Could be [ACCEPTED_THE_ORDER, FOOD_BEING_PREPARED, FOOD_PICKED_UP_BY_DELIVERY_PARTNER, 19 | DELIVERY_IS_IN_TRANSITION, FOOD_DELIVERED] 20 | 2. During Payment for Movie booking or food [PAYMENT_INITIATED, PAYMENT_PROCESSING, PAYMENT_COMPLETED, PAYMENT_FAILED] 21 | 3. In Amazon Delivery Track [ITEM_NOT_YET_DISPATCHED, ITEM_IS_IN_HUB1, ITEM_IS_IN_HUB2, ITEM_DELIVERED] 22 | 1. here if we return bck [ITEM_PICKUP ...] 23 | 24 | The Basic idea all were sequential if we change the state a some point then everything goes in sequential 25 | 26 | Downsides 27 | ---------- 28 | State pattern drawback is the payoff when implementing transition between the states. 29 | That makes the state hardcoded, which is a bad practice in general. 30 | But, depending on our needs and requirements, that might or might not be an issue 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/behavioral/state/state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/state/state.png -------------------------------------------------------------------------------- /src/behavioral/strategy/Data.java: -------------------------------------------------------------------------------- 1 | package behavioral.strategy; 2 | 3 | public class Data { 4 | private final META_DATA metadata; 5 | 6 | public Data(META_DATA metadata){ 7 | this.metadata = metadata; 8 | } 9 | 10 | public META_DATA getMetadata() { 11 | return metadata; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/behavioral/strategy/HTMLProcessor.java: -------------------------------------------------------------------------------- 1 | package behavioral.strategy; 2 | 3 | public class HTMLProcessor implements Processor { 4 | @Override 5 | public boolean process(Data data) { 6 | System.out.println("HTML Data processed: "+data.getMetadata()); 7 | return true; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/behavioral/strategy/JSONProcessor.java: -------------------------------------------------------------------------------- 1 | package behavioral.strategy; 2 | 3 | public class JSONProcessor implements Processor { 4 | @Override 5 | public boolean process(Data data) { 6 | System.out.println("JSON Data processed: "+data.getMetadata()); 7 | return true; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/behavioral/strategy/META_DATA.java: -------------------------------------------------------------------------------- 1 | package behavioral.strategy; 2 | 3 | public enum META_DATA { 4 | PLAIN, 5 | HTML, 6 | JSON 7 | } 8 | -------------------------------------------------------------------------------- /src/behavioral/strategy/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.strategy; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | Data data = new Data(META_DATA.HTML); 6 | 7 | Processor processor; 8 | 9 | switch (data.getMetadata()){ 10 | case HTML: 11 | processor = new HTMLProcessor(); 12 | System.out.println(processor.process(data)); 13 | return; 14 | case JSON: 15 | processor = new JSONProcessor(); 16 | System.out.println(processor.process(data)); 17 | return; 18 | case PLAIN: 19 | processor = new PlainTextProcessor(); 20 | System.out.println(processor.process(data)); 21 | return; 22 | default: 23 | System.out.println("Meta Data Not Supported "+data.getMetadata()); 24 | break; 25 | 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/behavioral/strategy/PlainTextProcessor.java: -------------------------------------------------------------------------------- 1 | package behavioral.strategy; 2 | 3 | public class PlainTextProcessor implements Processor { 4 | @Override 5 | public boolean process(Data data) { 6 | System.out.println("Plain Test Data processed "+data.getMetadata()); 7 | return true; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/behavioral/strategy/Processor.java: -------------------------------------------------------------------------------- 1 | package behavioral.strategy; 2 | 3 | // Strategy 4 | public interface Processor { 5 | 6 | boolean process(Data data); 7 | } 8 | -------------------------------------------------------------------------------- /src/behavioral/strategy/strategy.md: -------------------------------------------------------------------------------- 1 | Intent 2 | -------- 3 | Define a family of algorithms, encapsulate each one, and make them interchangeable. 4 | Strategy lets the algorithm vary independently of clients that use it. 5 | 6 | Uses 7 | 1. In Machine Learning after many models deployed with different algorithms next this is to test the models' 8 | efficiency from user data. So here with strategy pattern we can test different models for each set of users. 9 | client code has complete control over deciding what can be called. 10 | 2. During Festival season a company can offer discount program like 50% Discount, Easter Bonanza, Festival offer 11 | we can avail different offers based on eve. 12 | 3. Another way we can call this as policy depending on the customer data either we can Parse as Plain text or Json 13 | or HTML etc. 14 | 15 | Class Diagram 16 | 17 | ![img.png](strategy.png) -------------------------------------------------------------------------------- /src/behavioral/strategy/strategy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/strategy/strategy.png -------------------------------------------------------------------------------- /src/behavioral/templatemethod/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.templatemethod; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | PizzaMaker vegPizzaMaker = new VegPizzaMaker(); 6 | vegPizzaMaker.makePizza(); 7 | 8 | System.out.println("------------------------------"); 9 | PizzaMaker nvPizzaMaker = new NonVegPizzaMaker(); 10 | nvPizzaMaker.makePizza(); 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/behavioral/templatemethod/NonVegPizzaMaker.java: -------------------------------------------------------------------------------- 1 | package behavioral.templatemethod; 2 | 3 | public class NonVegPizzaMaker extends PizzaMaker { 4 | @Override 5 | public void prepareIngredients() { 6 | System.out.println("Preparing chicken ham, onion, chicken sausages, and smoked chicken"); 7 | } 8 | @Override 9 | public void addToppings() { 10 | System.out.println("Adding cheese, pepper jelly, and BBQ sauce along with ingredients to crust."); 11 | } 12 | } -------------------------------------------------------------------------------- /src/behavioral/templatemethod/PizzaMaker.java: -------------------------------------------------------------------------------- 1 | package behavioral.templatemethod; 2 | 3 | public abstract class PizzaMaker { 4 | public void makePizza() { 5 | preparePizzaDough(); 6 | preBakeCrust(); 7 | prepareIngredients(); 8 | addToppings(); 9 | bakePizza(); 10 | if (customerWantsPackedPizza()) { 11 | packPizza(); 12 | } 13 | } 14 | final void preparePizzaDough() { 15 | System.out.println("Preparing pizza dough with plain flour, dried yeast, caster sugar, salt, olive oil, and warm water."); 16 | } 17 | final void preBakeCrust() { 18 | System.out.println("Pre baking crust at 325 F for 3 minutes."); 19 | } 20 | abstract void prepareIngredients(); 21 | abstract void addToppings(); 22 | void bakePizza() { 23 | System.out.println("Baking pizza at 400 F for 12 minutes."); 24 | } 25 | void packPizza() { 26 | System.out.println("Packing pizza in pizza delivery box."); 27 | } 28 | boolean customerWantsPackedPizza() { 29 | return true; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/behavioral/templatemethod/VegPizzaMaker.java: -------------------------------------------------------------------------------- 1 | package behavioral.templatemethod; 2 | 3 | public class VegPizzaMaker extends PizzaMaker { 4 | @Override 5 | public void prepareIngredients() { 6 | System.out.println("Preparing mushroom, tomato slices, onions, and fresh basil leaves."); 7 | } 8 | @Override 9 | public void addToppings() { 10 | System.out.println("Adding mozzerella cheese and tomato sauce along with ingredients to crust."); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/behavioral/templatemethod/tempalte_method.md: -------------------------------------------------------------------------------- 1 | Intent 2 | -------- 3 | Define the skeleton of an algorithm in an operation, deferring some steps to 4 | subclasses. 5 | Template Method lets subclasses redefine certain steps of an algorithm 6 | without changing the algorithm's structure. 7 | 8 | The template methodology is adopted in frameworks, in which each applies the domain's immutable 9 | components while allowing "placeholders" for modification choices. 10 | 11 | For the reasons listed below, the template technique is used: 12 | 13 | 1. Template method design pattern allows subclasses to specify behavioural patterns which are achieved by using the concept of method overriding. 14 | 2. To prevent code duplication, the overall workflow structure is applied once in the algorithm of the abstract class, as well as any changes are applied in the subclasses. 15 | 3. Limit the points at which subclassing is permitted. Unlike a basic polymorphic override, in which the underlying function is completely rebuilt, 16 | enabling drastic changes to the workflow, just the specifics of the process are permitted to alter. 17 | 18 | ![img.png](tenplate.png) 19 | 20 | AbstractClass (Application) 21 | - defines abstract primitive operations that concrete subclasses define to 22 | implement steps of an algorithm. 23 | - implements a template method defining the skeleton of an algorithm. The 24 | template method calls primitive operations as well as operations defined 25 | in AbstractClass or those of other objects. 26 | ConcreteClass (MyApplication) 27 | - implements the primitive operations to carry out subclass-specific steps of the algorithm 28 | 29 | **Examples** 30 | 31 | 1. House Construction 32 | * buildFoundation(); 33 | * buildPillars(); 34 | * buildWalls(); 35 | * buildWindows(); 36 | 2. Build Computer 37 | * addMotherboard(); 38 | * setupMotherboard(); 39 | * addProcessor(); -------------------------------------------------------------------------------- /src/behavioral/templatemethod/tenplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/templatemethod/tenplate.png -------------------------------------------------------------------------------- /src/behavioral/visitor/AreaVisitor.java: -------------------------------------------------------------------------------- 1 | package behavioral.visitor; 2 | 3 | public class AreaVisitor implements ShapeVisitor { 4 | private double area; 5 | 6 | // Pi*r2 7 | @Override 8 | public void visit(final Circle circle) { 9 | area = Math.PI * Math.pow(circle.getRadius(), 2); 10 | } 11 | 12 | // 2*l 13 | @Override 14 | public void visit(final Square square) { 15 | area = 2 * square.getLength(); 16 | } 17 | 18 | // l*b 19 | @Override 20 | public void visit(final Rectangle rectangle) { 21 | area = rectangle.getLength() * rectangle.getWidth(); 22 | } 23 | 24 | public double get() { 25 | return this.area; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/behavioral/visitor/Circle.java: -------------------------------------------------------------------------------- 1 | package behavioral.visitor; 2 | 3 | public class Circle implements Shape { 4 | private final double radius; 5 | 6 | public Circle(final double radius) { 7 | this.radius = radius; 8 | } 9 | 10 | public double getRadius() { 11 | return radius; 12 | } 13 | 14 | @Override 15 | public void accept(final ShapeVisitor visitor) { 16 | visitor.visit(this); 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/behavioral/visitor/Main.java: -------------------------------------------------------------------------------- 1 | package behavioral.visitor; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Main { 7 | public static void main(String[] args) { 8 | final List shapes = new ArrayList<>(); 9 | 10 | shapes.add(new Circle(10)); 11 | shapes.add(new Square(10)); 12 | shapes.add(new Rectangle(10, 2)); 13 | 14 | final AreaVisitor areaVisitor = new AreaVisitor(); 15 | final PerimeterVisitor perimeterVisitor = new PerimeterVisitor(); 16 | 17 | for (Shape shape: shapes) { 18 | shape.accept(areaVisitor); 19 | final double area = areaVisitor.get(); 20 | 21 | System.out.printf( 22 | "Area of %s: %.2f%n", 23 | shape.getClass().getSimpleName(), 24 | area 25 | ); 26 | } 27 | 28 | System.out.println("---------------------------------"); 29 | 30 | for (Shape shape: shapes) { 31 | shape.accept(perimeterVisitor); 32 | final double perimeter = perimeterVisitor.get(); 33 | 34 | System.out.printf( 35 | "Perimeter of %s: %.2f%n", 36 | shape.getClass().getSimpleName(), 37 | perimeter 38 | ); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/behavioral/visitor/PerimeterVisitor.java: -------------------------------------------------------------------------------- 1 | package behavioral.visitor; 2 | 3 | public class PerimeterVisitor implements ShapeVisitor { 4 | private double perimeter; 5 | 6 | // 2*pi*r 7 | @Override 8 | public void visit(final Circle circle) { 9 | perimeter = 2 * Math.PI * circle.getRadius(); 10 | } 11 | 12 | // 4*a 13 | @Override 14 | public void visit(final Square square) { 15 | perimeter = 4 * square.getLength(); 16 | } 17 | 18 | // 2*(l+b) 19 | @Override 20 | public void visit(final Rectangle rectangle) { 21 | perimeter = 2 * (rectangle.getLength() + rectangle.getWidth()); 22 | } 23 | 24 | public double get() { 25 | return this.perimeter; 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /src/behavioral/visitor/Rectangle.java: -------------------------------------------------------------------------------- 1 | package behavioral.visitor; 2 | 3 | public class Rectangle implements Shape { 4 | private final double length; 5 | private final double width; 6 | 7 | public Rectangle(final double length, final double width) { 8 | this.length = length; 9 | this.width = width; 10 | } 11 | 12 | public double getLength() { 13 | return length; 14 | } 15 | 16 | public double getWidth() { 17 | return width; 18 | } 19 | 20 | @Override 21 | public void accept(final ShapeVisitor visitor) { 22 | visitor.visit(this); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/behavioral/visitor/Shape.java: -------------------------------------------------------------------------------- 1 | package behavioral.visitor; 2 | 3 | // Object - element 4 | public interface Shape { 5 | void accept(ShapeVisitor visitor); 6 | } 7 | -------------------------------------------------------------------------------- /src/behavioral/visitor/ShapeVisitor.java: -------------------------------------------------------------------------------- 1 | package behavioral.visitor; 2 | 3 | public interface ShapeVisitor { 4 | void visit(Circle circle); 5 | void visit(Square square); 6 | void visit(Rectangle rectangle); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/behavioral/visitor/Square.java: -------------------------------------------------------------------------------- 1 | package behavioral.visitor; 2 | 3 | public class Square implements Shape { 4 | private final double length; 5 | 6 | public Square(final double length) { 7 | this.length = length; 8 | } 9 | 10 | public double getLength() { 11 | return length; 12 | } 13 | 14 | @Override 15 | public void accept(final ShapeVisitor visitor) { 16 | visitor.visit(this); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/behavioral/visitor/visitor.md: -------------------------------------------------------------------------------- 1 | INTENT 2 | ---------- 3 | 4 | *The purpose of a Visitor pattern is to define a new operation without introducing the modifications to an existing object structure.* 5 | 6 | used to decouple the logic/algorithm from the objects on which they operate. The logic is moved to separate classes called visitors. 7 | 8 | Each visitor is responsible for performing a specific operation. 9 | 10 | ![img.png](visitor.png) 11 | 12 | Explanation 13 | 14 | ![exp](visitor_exp.png) -------------------------------------------------------------------------------- /src/behavioral/visitor/visitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/visitor/visitor.png -------------------------------------------------------------------------------- /src/behavioral/visitor/visitor_exp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/behavioral/visitor/visitor_exp.png -------------------------------------------------------------------------------- /src/creational/Creational Design Patterns.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/creational/Creational Design Patterns.md -------------------------------------------------------------------------------- /src/creational/abstractfactory/AbstractFactory.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory; 2 | 3 | public interface AbstractFactory { 4 | T create(E type); 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/AbstractFactory.md: -------------------------------------------------------------------------------- 1 | Intent 2 | --------- 3 | Provide an interface for creating families of related or dependent objects without 4 | specifying their concrete classes. 5 | 6 | _Abstraction over multiple factory patterns_ 7 | 8 | **Abstraction** is the process of hiding certain details and showing only essential information to the user 9 | 10 | Simply Called : Factory for multiple independent factory patterns 11 | 12 | ![img.png](img.png) 13 | 14 | Simply we can say abstraction over Multiple Factories 15 | 16 | Applicability 17 | ------------- 18 | Use the Abstract Factory pattern when 19 | 1. a system should be independent of how its products are created, composed, and represented. 20 | 2. a system should be configured with one of multiple families of products. 21 | 3. a family of related product objects is designed to be used together, and you need to enforce this constraint. 22 | 4. you want to provide a class library of products, and you want to reveal just their interfaces, not their implementations. -------------------------------------------------------------------------------- /src/creational/abstractfactory/AbstractFactoryProvider.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory; 2 | 3 | import creational.abstractfactory.exception.ObjectCreationException; 4 | 5 | public class AbstractFactoryProvider { 6 | 7 | public static AbstractFactory getFactory(ObjectType objectType){ 8 | 9 | switch (objectType){ 10 | case BANK: return new BankFactory(); 11 | case LOAN: return new LoanFactory(); 12 | default: throw new ObjectCreationException(objectType.toString()); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/BankFactory.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory; 2 | 3 | import creational.abstractfactory.bank.Bank; 4 | import creational.abstractfactory.bank.BankType; 5 | import creational.abstractfactory.bank.HDFC; 6 | import creational.abstractfactory.bank.ICICI; 7 | import creational.abstractfactory.bank.SBI; 8 | import creational.abstractfactory.exception.ObjectCreationException; 9 | 10 | public class BankFactory implements AbstractFactory { 11 | 12 | @Override 13 | public Bank create(BankType type) { 14 | switch (type){ 15 | case SBI: return new SBI(); 16 | case HDFC: return new HDFC(); 17 | case ICICI: return new ICICI(); 18 | default: throw new ObjectCreationException(type.toString()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/Driver.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory; 2 | 3 | import creational.abstractfactory.bank.Bank; 4 | import creational.abstractfactory.bank.BankType; 5 | import creational.abstractfactory.loan.Loan; 6 | import creational.abstractfactory.loan.LoanType; 7 | 8 | public class Driver { 9 | public static void main(String[] args) { 10 | AbstractFactory bankTypeAbstractFactory = AbstractFactoryProvider.getFactory(ObjectType.BANK); 11 | Bank bank = bankTypeAbstractFactory.create(BankType.HDFC); 12 | System.out.println(bank.getBankName()); 13 | 14 | AbstractFactory loanTypeAbstractFactory = AbstractFactoryProvider.getFactory(ObjectType.LOAN); 15 | Loan loan = loanTypeAbstractFactory.create(LoanType.PERSONAL); 16 | System.out.println(loan.getInterestRate()); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/LoanFactory.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory; 2 | 3 | 4 | import creational.abstractfactory.exception.ObjectCreationException; 5 | import creational.abstractfactory.loan.EducationalLoan; 6 | import creational.abstractfactory.loan.HomeLoan; 7 | import creational.abstractfactory.loan.Loan; 8 | import creational.abstractfactory.loan.LoanType; 9 | import creational.abstractfactory.loan.PersonalLoan; 10 | 11 | public class LoanFactory implements AbstractFactory{ 12 | @Override 13 | public Loan create(LoanType type) { 14 | switch (type){ 15 | case PERSONAL: return new PersonalLoan(); 16 | case HOME: return new HomeLoan(); 17 | case EDUCATIONAL: return new EducationalLoan(); 18 | default: throw new ObjectCreationException(type.toString()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/ObjectType.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory; 2 | 3 | public enum ObjectType { 4 | BANK, 5 | LOAN; 6 | } 7 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/bank/Bank.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory.bank; 2 | 3 | public interface Bank { 4 | String getBankName(); 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/bank/BankType.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory.bank; 2 | 3 | public enum BankType { 4 | HDFC, 5 | ICICI, 6 | SBI; 7 | } 8 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/bank/HDFC.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory.bank; 2 | 3 | public class HDFC implements Bank{ 4 | 5 | String name; 6 | 7 | public HDFC(){ 8 | this.name = "HDFC"; 9 | } 10 | 11 | @Override 12 | public String getBankName() { 13 | return name; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/bank/ICICI.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory.bank; 2 | 3 | public class ICICI implements Bank{ 4 | 5 | String name; 6 | 7 | public ICICI(){ 8 | this.name = "ICICI"; 9 | } 10 | 11 | @Override 12 | public String getBankName() { 13 | return name; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/bank/SBI.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory.bank; 2 | 3 | public class SBI implements Bank{ 4 | 5 | String name; 6 | 7 | public SBI(){ 8 | this.name = "SBI"; 9 | } 10 | 11 | @Override 12 | public String getBankName() { 13 | return name; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/exception/ObjectCreationException.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory.exception; 2 | 3 | public class ObjectCreationException extends RuntimeException{ 4 | 5 | public ObjectCreationException(String message){ 6 | System.out.println(message+" Object Creation Failed"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/creational/abstractfactory/img.png -------------------------------------------------------------------------------- /src/creational/abstractfactory/loan/EducationalLoan.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory.loan; 2 | 3 | public class EducationalLoan implements Loan{ 4 | 5 | private static final double interestRate = 6.5; 6 | 7 | @Override 8 | public double getInterestRate() { 9 | System.out.println("Educational Loan"); 10 | return interestRate; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/loan/HomeLoan.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory.loan; 2 | 3 | public class HomeLoan implements Loan{ 4 | 5 | private static final double interestRate = 7.5; 6 | 7 | @Override 8 | public double getInterestRate() { 9 | System.out.println("Home Loan"); 10 | return interestRate; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/loan/Loan.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory.loan; 2 | 3 | public interface Loan { 4 | double getInterestRate(); 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/loan/LoanType.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory.loan; 2 | 3 | public enum LoanType { 4 | HOME, 5 | PERSONAL, 6 | EDUCATIONAL; 7 | } 8 | -------------------------------------------------------------------------------- /src/creational/abstractfactory/loan/PersonalLoan.java: -------------------------------------------------------------------------------- 1 | package creational.abstractfactory.loan; 2 | 3 | public class PersonalLoan implements Loan{ 4 | 5 | private static final double interestRate = 10.5; 6 | 7 | @Override 8 | public double getInterestRate() { 9 | System.out.println("Personal Loan"); 10 | return interestRate; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/creational/builder/Builder.md: -------------------------------------------------------------------------------- 1 | **Intent** 2 | ----------- 3 | Separate the construction of a complex object from its representation so that the 4 | same construction process can create different representations. 5 | 6 | ![builder.png](builder.png) 7 | 8 | **Usage examples** 9 | -------------------- 10 | * The Builder pattern is a well-known pattern in Java world. 11 | * It’s especially useful when you need to create an object with lots of possible configuration options. 12 | 13 | 14 | _There are three major issues with Factory and Abstract Factory design patterns when the Object contains a lot of attributes._ 15 | 16 | 1. Too Many arguments to pass from client program to the Factory class that can be error prone because most of the time, the type of arguments are same and from client side its hard to maintain the order of the argument. 17 | 2. Some parameters might be optional but in Factory pattern, we are forced to send all the parameters and optional parameters need to send as NULL. 18 | 3. If the object is heavy and its creation is complex, then all that complexity will be part of Factory classes that is confusing. 19 | 20 | 21 | *We can solve the issues with large number of parameters by providing a constructor with required parameters and then different setter methods to set the optional parameters.* 22 | *The problem with this approach is that the Object state will be inconsistent until unless all the attributes are set explicitly.* 23 | 24 | *Builder pattern solves the issue with large number of optional parameters and inconsistent state by providing 25 | a way to build the object step-by-step and provide a method that will actually return the final Object* 26 | 27 | **Important Considerations** 28 | 1. When we have too many optional fields 29 | 2. A different way of defining object immutability 30 | 3. When we want restriction over fields access hierarchy 31 | 32 | **Here I am talking about Implementing** 33 | 1. User Builder ( have required and optional fields) 34 | 2. Car Builder (Normal Builder and Priority Fields Builder) -------------------------------------------------------------------------------- /src/creational/builder/Driver.java: -------------------------------------------------------------------------------- 1 | package creational.builder; 2 | 3 | import creational.builder.withoutpriorityfields.Car; 4 | import creational.builder.withpriorityfields.CarBuilder; 5 | 6 | public class Driver { 7 | public static void main(String[] args) { 8 | 9 | // User Builder - With Mandatory and Optional Fields 10 | User user = new User.UserBuilder("LavaKumar","T").build(); 11 | System.out.println(user); 12 | 13 | user = new User.UserBuilder("LavaKumar","T").setAge(24).setPhone("9890098900").build(); 14 | System.out.println(user); 15 | 16 | // Car Builder - 17 | Car car = new Car.CarBuilder().setColor("Red").setEnginePower("200cc").setNoOfSeats(7).build(); 18 | System.out.println(car); 19 | 20 | // Car Builder With Priority 21 | creational.builder.withpriorityfields.Car priorityCar = 22 | CarBuilder.getInstance().seatCapacity(10).enginePower("150cc").color("Red").build(); 23 | 24 | System.out.println(priorityCar); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/creational/builder/User.java: -------------------------------------------------------------------------------- 1 | package creational.builder; 2 | 3 | public class User { 4 | private final String firstName; // required 5 | private final String lastName; // required 6 | private final int age; // optional 7 | private final String phone; // optional 8 | 9 | public User(UserBuilder builder) { 10 | this.firstName = builder.firstName; 11 | this.lastName = builder.lastName; 12 | this.age = builder.age; 13 | this.phone = builder.phone; 14 | } 15 | 16 | public String getFirstName() { 17 | return firstName; 18 | } 19 | public String getLastName() { 20 | return lastName; 21 | } 22 | public int getAge() { 23 | return age; 24 | } 25 | public String getPhone() { 26 | return phone; 27 | } 28 | 29 | public static class UserBuilder { 30 | private final String firstName; 31 | private final String lastName; 32 | private int age; 33 | private String phone; 34 | 35 | // Mandatory Fields 36 | public UserBuilder(String firstName, String lastName) { 37 | this.firstName = firstName; 38 | this.lastName = lastName; 39 | } 40 | 41 | public UserBuilder setAge(int age){ 42 | this.age = age; 43 | return this; 44 | } 45 | 46 | public UserBuilder setPhone(String phone){ 47 | this.phone = phone; 48 | return this; 49 | } 50 | 51 | public User build(){ 52 | return new User(this); 53 | } 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | return "User{" + 59 | "firstName='" + firstName + '\'' + 60 | ", lastName='" + lastName + '\'' + 61 | ", age=" + age + 62 | ", phone='" + phone + '\'' + 63 | '}'; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/creational/builder/builder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/creational/builder/builder.png -------------------------------------------------------------------------------- /src/creational/builder/withoutpriorityfields/Car.java: -------------------------------------------------------------------------------- 1 | package creational.builder.withoutpriorityfields; 2 | 3 | /* 4 | Fields 5 | ------ 6 | - noOfSeats 7 | - color 8 | - enginePower 9 | */ 10 | public class Car { 11 | private final Integer noOfSeats; 12 | private final String enginePower; 13 | private final String color; 14 | 15 | public Car(CarBuilder carBuilder) { 16 | this.noOfSeats = carBuilder.noOfSeats; 17 | this.enginePower = carBuilder.enginePower; 18 | this.color = carBuilder.color; 19 | } 20 | 21 | public Integer getNoOfSeats() { 22 | return noOfSeats; 23 | } 24 | 25 | public String getEnginePower() { 26 | return enginePower; 27 | } 28 | 29 | public String getColor() { 30 | return color; 31 | } 32 | 33 | public static class CarBuilder { 34 | private Integer noOfSeats; 35 | private String enginePower; 36 | private String color; 37 | 38 | public CarBuilder setNoOfSeats(Integer noOfSeats){ 39 | this.noOfSeats = noOfSeats; 40 | return this; 41 | } 42 | public CarBuilder setEnginePower(String enginePower){ 43 | this.enginePower = enginePower; 44 | return this; 45 | } 46 | public CarBuilder setColor(String color){ 47 | this.color = color; 48 | return this; 49 | } 50 | public Car build(){ 51 | return new Car(this); 52 | } 53 | 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | return "Car{" + 59 | "noOfSeats=" + noOfSeats + 60 | ", enginePower='" + enginePower + '\'' + 61 | ", color='" + color + '\'' + 62 | '}'; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/creational/builder/withpriorityfields/Car.java: -------------------------------------------------------------------------------- 1 | package creational.builder.withpriorityfields; 2 | 3 | /* 4 | Fields 5 | ------ 6 | - noOfSeats 7 | - color 8 | - enginePower 9 | 10 | Without Setting color We cannot set Engine Power 11 | Without Setting Engine Power We cannot Set No Of Seats 12 | Hierarchy set No Of Seats - Engine Power - Color 13 | 14 | Hierarchy set No Of Seats (Engine Power) - Engine Power ( Color) - Color (Car Builder) 15 | 16 | Program to Interfaces 17 | */ 18 | 19 | public class Car { 20 | private final Integer noOfSeats; 21 | private final String enginePower; 22 | private final String color; 23 | 24 | public Car(Integer noOfSeats, String enginePower, String color) { 25 | this.noOfSeats = noOfSeats; 26 | this.enginePower = enginePower; 27 | this.color = color; 28 | } 29 | 30 | public Integer getNoOfSeats() { 31 | return noOfSeats; 32 | } 33 | 34 | public String getEnginePower() { 35 | return enginePower; 36 | } 37 | 38 | public String getColor() { 39 | return color; 40 | } 41 | 42 | 43 | 44 | 45 | @Override 46 | public String toString() { 47 | return "Car{" + 48 | "noOfSeats=" + noOfSeats + 49 | ", enginePower='" + enginePower + '\'' + 50 | ", color='" + color + '\'' + 51 | '}'; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/creational/builder/withpriorityfields/CarBuilder.java: -------------------------------------------------------------------------------- 1 | package creational.builder.withpriorityfields; 2 | 3 | public class CarBuilder implements Color, EnginePower, SeatCapacity { 4 | private Integer noOfSeats; 5 | private String enginePower; 6 | private String color; 7 | 8 | public static SeatCapacity getInstance(){ 9 | return new CarBuilder(); 10 | } 11 | 12 | @Override 13 | public EnginePower seatCapacity(Integer noOfSeats) { 14 | this.noOfSeats = noOfSeats; 15 | return this; 16 | } 17 | 18 | @Override 19 | public Color enginePower(String enginePower) { 20 | this.enginePower = enginePower; 21 | return this; 22 | } 23 | 24 | @Override 25 | public CarBuilder color(String color) { 26 | this.color = color; 27 | return this; 28 | } 29 | 30 | public Car build(){ 31 | return new Car(this.noOfSeats, this.enginePower, this.color); 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/creational/builder/withpriorityfields/Color.java: -------------------------------------------------------------------------------- 1 | package creational.builder.withpriorityfields; 2 | 3 | public interface Color { 4 | CarBuilder color(String color); 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/builder/withpriorityfields/EnginePower.java: -------------------------------------------------------------------------------- 1 | package creational.builder.withpriorityfields; 2 | 3 | public interface EnginePower { 4 | Color enginePower(String enginePower); 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/builder/withpriorityfields/SeatCapacity.java: -------------------------------------------------------------------------------- 1 | package creational.builder.withpriorityfields; 2 | 3 | public interface SeatCapacity { 4 | EnginePower seatCapacity(Integer setCapacity); 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/factory/Factory.md: -------------------------------------------------------------------------------- 1 | **Intent** 2 | ---------- 3 | Define an interface for creating an object, but let subclasses decide which class to 4 | instantiate. Factory Method lets a class defer instantiation to subclasses. 5 | 6 | Also called - *Virtual Constructor* 7 | 8 | It promotes the loose-coupling by eliminating the need to bind application-specific classes into the code. 9 | 10 | ![factory.png](factory.png) -------------------------------------------------------------------------------- /src/creational/factory/createobject/Driver.java: -------------------------------------------------------------------------------- 1 | package creational.factory.createobject; 2 | 3 | public class Driver { 4 | public static void main(String[] args) { 5 | Resource2 resource2 = new Resource2(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/creational/factory/createobject/Resource1.java: -------------------------------------------------------------------------------- 1 | package creational.factory.createobject; 2 | 3 | public class Resource1 { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/factory/createobject/Resource2.java: -------------------------------------------------------------------------------- 1 | package creational.factory.createobject; 2 | 3 | public class Resource2 { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/factory/createobject/Resource3.java: -------------------------------------------------------------------------------- 1 | package creational.factory.createobject; 2 | 3 | public class Resource3 { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/factory/factory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/creational/factory/factory.png -------------------------------------------------------------------------------- /src/creational/factory/notification/Driver.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notification; 2 | 3 | public class Driver { 4 | 5 | public static void main(String[] args) { 6 | 7 | NotificationAttributes attributes = new NotificationAttributes( 8 | "9890098900","878787013","Your Mobile OTP : 35654 valid for 10 minus" 9 | ); 10 | 11 | Notification notification = NotificationFactory.getInstance(NotificationType.SMS); 12 | 13 | notification.sendNotification(attributes); 14 | 15 | notification = NotificationFactory.getInstance(NotificationType.EMAIL); 16 | 17 | notification.sendNotification(attributes); 18 | 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/creational/factory/notification/EmailNotification.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notification; 2 | 3 | public class EmailNotification implements Notification { 4 | @Override 5 | public boolean sendNotification(NotificationAttributes notificationAttributes) { 6 | System.out.println("Email Send Successfully to :"+notificationAttributes.getTo()); 7 | return true; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/creational/factory/notification/Notification.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notification; 2 | 3 | public interface Notification { 4 | boolean sendNotification(NotificationAttributes notificationAttributes); 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/factory/notification/NotificationAttributes.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notification; 2 | 3 | public class NotificationAttributes { 4 | private final String from; 5 | private final String to; 6 | private final String message; 7 | // Can add extra Fields all comes under Metadata 8 | 9 | public NotificationAttributes(String from, String to, String message) { 10 | this.from = from; 11 | this.to = to; 12 | this.message = message; 13 | } 14 | 15 | public String getFrom() { 16 | return from; 17 | } 18 | 19 | public String getTo() { 20 | return to; 21 | } 22 | 23 | public String getMessage() { 24 | return message; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/creational/factory/notification/NotificationFactory.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notification; 2 | 3 | import java.util.HashMap; 4 | 5 | public class NotificationFactory { 6 | 7 | private static final HashMap factoryMap = new HashMap<>(); 8 | 9 | static { 10 | // Will Take More about Creating Objects While we talk about Singleton Pattern 11 | factoryMap.put(NotificationType.APP, new PushNotification()); 12 | factoryMap.put(NotificationType.EMAIL, new EmailNotification()); 13 | factoryMap.put(NotificationType.SMS, new SMSNotification()); 14 | } 15 | 16 | public static Notification getInstance(NotificationType notificationType){ 17 | 18 | return factoryMap.get(notificationType); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/creational/factory/notification/NotificationType.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notification; 2 | 3 | public enum NotificationType { 4 | APP, 5 | SMS, 6 | EMAIL; 7 | } 8 | -------------------------------------------------------------------------------- /src/creational/factory/notification/PushNotification.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notification; 2 | 3 | public class PushNotification implements Notification { 4 | @Override 5 | public boolean sendNotification(NotificationAttributes notificationAttributes) { 6 | // Here From his Which Server is Sent and to is our device UDID 7 | System.out.println("App Notification Sent Successfully to :"+notificationAttributes.getTo()); 8 | return true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/creational/factory/notification/SMSNotification.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notification; 2 | 3 | public class SMSNotification implements Notification { 4 | @Override 5 | public boolean sendNotification(NotificationAttributes notificationAttributes) { 6 | System.out.println("SMS Send Successfully to - "+notificationAttributes.getTo()); 7 | return true; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/creational/factory/notificationwithoutpattern/Driver.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notificationwithoutpattern; 2 | 3 | public class Driver { 4 | 5 | public static void main(String[] args) { 6 | 7 | NotificationAttributes attributes = new NotificationAttributes( 8 | "9890098900","878787013","Your Mobile OTP : 35654 valid for 10 minus" 9 | ); 10 | 11 | Notification notification = new SMSNotification(); 12 | 13 | notification.sendNotification(attributes); 14 | 15 | attributes = new NotificationAttributes( 16 | "lava@gmail.com","kumar@gmail.com","Your Service OTP : 35654 valid for 10 minus" 17 | ); 18 | 19 | notification = new EmailNotification(); 20 | 21 | notification.sendNotification(attributes); 22 | 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/creational/factory/notificationwithoutpattern/EmailNotification.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notificationwithoutpattern; 2 | 3 | public class EmailNotification implements Notification { 4 | @Override 5 | public boolean sendNotification(NotificationAttributes notificationAttributes) { 6 | System.out.println("Email Send Successfully to :"+notificationAttributes.getTo()); 7 | return true; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/creational/factory/notificationwithoutpattern/Notification.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notificationwithoutpattern; 2 | 3 | public interface Notification { 4 | boolean sendNotification(NotificationAttributes notificationAttributes); 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/factory/notificationwithoutpattern/NotificationAttributes.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notificationwithoutpattern; 2 | 3 | public class NotificationAttributes { 4 | private final String from; 5 | private final String to; 6 | private final String message; 7 | // Can add extra Fields all comes under Metadata 8 | 9 | public NotificationAttributes(String from, String to, String message) { 10 | this.from = from; 11 | this.to = to; 12 | this.message = message; 13 | } 14 | 15 | public String getFrom() { 16 | return from; 17 | } 18 | 19 | public String getTo() { 20 | return to; 21 | } 22 | 23 | public String getMessage() { 24 | return message; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/creational/factory/notificationwithoutpattern/PushNotification.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notificationwithoutpattern; 2 | 3 | public class PushNotification implements Notification { 4 | @Override 5 | public boolean sendNotification(NotificationAttributes notificationAttributes) { 6 | // Here From his Which Server is Sent and to is our device UDID 7 | System.out.println("App Notification Sent Successfully to :"+notificationAttributes.getTo()); 8 | return true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/creational/factory/notificationwithoutpattern/SMSNotification.java: -------------------------------------------------------------------------------- 1 | package creational.factory.notificationwithoutpattern; 2 | 3 | public class SMSNotification implements Notification { 4 | @Override 5 | public boolean sendNotification(NotificationAttributes notificationAttributes) { 6 | System.out.println("SMS Send Successfully to - "+notificationAttributes.getTo()); 7 | return true; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/creational/prototype/Driver.java: -------------------------------------------------------------------------------- 1 | package creational.prototype; 2 | 3 | public class Driver { 4 | public static void main(String[] args) { 5 | Employee employee1 = new Employee(1,"Lava Kumar",24,10000000); 6 | 7 | System.out.println(employee1); 8 | System.out.println(employee1.hashCode()); 9 | 10 | 11 | 12 | 13 | Employee employee2 = (Employee) employee1.clone(); 14 | System.out.println(employee2); 15 | System.out.println(employee2.hashCode()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/creational/prototype/Employee.java: -------------------------------------------------------------------------------- 1 | package creational.prototype; 2 | 3 | public class Employee implements Prototype { 4 | private final Integer id; 5 | private final String name; 6 | private final Integer age; 7 | private final double salary; 8 | 9 | public Employee(Integer id, String name, Integer age, double salary) { 10 | this.id = id; 11 | this.name = name; 12 | this.age = age; 13 | this.salary = salary; 14 | } 15 | 16 | public Integer getId() { 17 | return id; 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public Integer getAge() { 25 | return age; 26 | } 27 | 28 | public double getSalary() { 29 | return salary; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "Employee{" + 35 | "id=" + id + 36 | ", name='" + name + '\'' + 37 | ", age=" + age + 38 | ", salary=" + salary + 39 | '}'; 40 | } 41 | 42 | @Override 43 | public Prototype clone() { 44 | 45 | return new Employee(this.id, this.name, this.age, this.salary); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/creational/prototype/Prototype.java: -------------------------------------------------------------------------------- 1 | package creational.prototype; 2 | 3 | public interface Prototype { 4 | Prototype clone(); 5 | } 6 | -------------------------------------------------------------------------------- /src/creational/prototype/prototype.md: -------------------------------------------------------------------------------- 1 | **Intent** 2 | ---------- 3 | *Specify the kinds of objects to create using a prototypical instance, and create new 4 | objects by copying this prototype.* 5 | 6 | 7 | ![prototype.png](prototype.png) 8 | 9 | 1. The concept is to copy an existing object rather than creating a new instance from scratch, 10 | something that may include costly operations. 11 | 2. The existing object acts as a prototype and contains the state of the object. 12 | 3. The newly copied object may change same properties only if required. 13 | 4. This approach saves costly resources and time, especially when object creation is a heavy process. 14 | 15 | _Example:_ create an object from existing objects is the `clone()` method. -------------------------------------------------------------------------------- /src/creational/prototype/prototype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/creational/prototype/prototype.png -------------------------------------------------------------------------------- /src/creational/singleton/BillPughSingleton.java: -------------------------------------------------------------------------------- 1 | package creational.singleton; 2 | 3 | /* 4 | until we need an instance, the LazyHolder class will not be initialized until required, 5 | and you can still use other static members of BillPughSingleton class 6 | */ 7 | public class BillPughSingleton { 8 | private BillPughSingleton() { 9 | } 10 | private static class LazyHolder { 11 | private static final BillPughSingleton INSTANCE = new BillPughSingleton(); 12 | } 13 | public static BillPughSingleton getInstance() { 14 | return LazyHolder.INSTANCE; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/creational/singleton/DoubleLockSingleton.java: -------------------------------------------------------------------------------- 1 | package creational.singleton; 2 | 3 | 4 | public class DoubleLockSingleton { 5 | // Volatile keyword is used to modify the value of a variable by different threads 6 | // It means that multiple threads can use a method and instance of the classes at the same time without any problem 7 | private static volatile DoubleLockSingleton instance; 8 | 9 | private DoubleLockSingleton() { 10 | 11 | } 12 | 13 | /* 14 | When two threads T1 and T2 comes to create instance and execute ?instance==null?, 15 | both threads have identified instance variable to null thus assume they must create an instance. 16 | They sequentially go to synchronized block and create the instances. 17 | At the end, we have two instances in our application. 18 | */ 19 | public static DoubleLockSingleton getInstanceSingleCheck() { 20 | if (instance == null) { 21 | synchronized (DoubleLockSingleton.class) { 22 | instance = new DoubleLockSingleton(); 23 | } 24 | } 25 | return instance; 26 | } 27 | 28 | /* The above Issue can be resolved by Double Lock */ 29 | public static DoubleLockSingleton getInstance() { 30 | if (instance == null) { 31 | synchronized (DoubleLockSingleton.class) { 32 | // Double check 33 | if (instance == null) { // T1 - Obj 34 | instance = new DoubleLockSingleton(); 35 | } 36 | } 37 | } 38 | return instance; 39 | } 40 | 41 | // @Override 42 | // public int hashCode() { 43 | // return unique; 44 | // } 45 | } 46 | -------------------------------------------------------------------------------- /src/creational/singleton/Driver.java: -------------------------------------------------------------------------------- 1 | package creational.singleton; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | import java.util.Map; 6 | import java.util.Set; 7 | import java.util.concurrent.ExecutorService; 8 | import java.util.concurrent.Executors; 9 | import java.util.concurrent.TimeUnit; 10 | 11 | public class Driver { 12 | public static void main(String[] args) { 13 | 14 | ExecutorService executor = Executors.newFixedThreadPool(100); 15 | Set set = new HashSet<>(); 16 | System.out.println("Normal"); 17 | System.out.println("Total Created Instances: "); 18 | for (int i = 0; i < 100; i++) { 19 | Runnable worker = new NormalSingleTonRunnable(set); 20 | // execute(): Executes the given command at some time in the future. 21 | // The command may execute in a new thread, in a pooled thread, 22 | // or in the calling thread, at the discretion of the Executor implementation. 23 | executor.execute(worker); 24 | } 25 | awaitTerminationAfterShutdown(executor); 26 | executor = Executors.newFixedThreadPool(100); 27 | System.out.println("Double Lock"); 28 | System.out.println("Total Created Instances: "); 29 | set = new HashSet<>(); 30 | for (int i = 0; i < 100; i++) { 31 | Runnable worker = new DoubleLockSingleTonRunnable(set); 32 | // execute(): Executes the given command at some time in the future. 33 | // The command may execute in a new thread, in a pooled thread, 34 | // or in the calling thread, at the discretion of the Executor implementation. 35 | executor.execute(worker); 36 | } 37 | 38 | } 39 | 40 | public static class NormalSingleTonRunnable implements Runnable { 41 | NormalSingleton normalSingleton; 42 | Set set; 43 | 44 | NormalSingleTonRunnable(Set set) { 45 | this.set =set; 46 | } 47 | 48 | @Override 49 | public void run() { 50 | normalSingleton = NormalSingleton.getInstance(); 51 | System.out.println(normalSingleton.hashCode()); 52 | } 53 | } 54 | 55 | public static class DoubleLockSingleTonRunnable implements Runnable { 56 | DoubleLockSingleton singleton; 57 | Set set; 58 | 59 | DoubleLockSingleTonRunnable(Set set) { 60 | this.set =set; 61 | } 62 | 63 | @Override 64 | public void run() { 65 | singleton = DoubleLockSingleton.getInstance(); 66 | System.out.println(singleton.hashCode()); 67 | } 68 | 69 | } 70 | 71 | public static void awaitTerminationAfterShutdown(ExecutorService service) { 72 | service.shutdown(); 73 | try { 74 | if (!service.awaitTermination(60, TimeUnit.SECONDS)) { 75 | service.shutdownNow(); 76 | } 77 | } catch (InterruptedException ex) { 78 | service.shutdownNow(); 79 | Thread.currentThread().interrupt(); 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /src/creational/singleton/EagerSingleton.java: -------------------------------------------------------------------------------- 1 | package creational.singleton; 2 | 3 | /* 4 | This technique is used where an instance of a class is created much before it is actually required. 5 | Mostly it is done on system start up. 6 | In singleton pattern, it refers to create the singleton instance irrespective of whether any other class actually 7 | asked for its instance or not 8 | Drawback: 9 | Instance is created irrespective of it is required in runtime or not. 10 | If this instance is not big object, and you can live with it being unused, this is best approach. 11 | */ 12 | public class EagerSingleton { 13 | private static final EagerSingleton obj = new EagerSingleton(); 14 | 15 | private EagerSingleton() {} 16 | 17 | public static EagerSingleton getInstance() 18 | { 19 | return obj; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/creational/singleton/EnumBasedSingleton.java: -------------------------------------------------------------------------------- 1 | package creational.singleton; 2 | /* 3 | Enum provide implicit support for thread safety and only one instance is guaranteed 4 | */ 5 | public enum EnumBasedSingleton { 6 | INSTANCE; 7 | public void someMethod(String param) { 8 | // some class member 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/creational/singleton/NormalSingleton.java: -------------------------------------------------------------------------------- 1 | package creational.singleton; 2 | 3 | public class NormalSingleton { 4 | private static volatile NormalSingleton obj; 5 | private NormalSingleton() {} 6 | 7 | // It will not guarantee single instance created 8 | public static NormalSingleton getInstance() 9 | { 10 | if (obj==null) 11 | obj = new NormalSingleton(); 12 | return obj; 13 | } 14 | 15 | /* using synchronized every time while creating the singleton 16 | object is expensive and may decrease the performance of your program */ 17 | // public static synchronized NormalSingleton getInstance() 18 | // { 19 | // if (obj==null) 20 | // obj = new NormalSingleton(); 21 | // return obj; 22 | // } 23 | } 24 | -------------------------------------------------------------------------------- /src/creational/singleton/StaticBlockSingleton.java: -------------------------------------------------------------------------------- 1 | package creational.singleton; 2 | 3 | /* similar to Eager Singleton */ 4 | 5 | public class StaticBlockSingleton { 6 | private static final StaticBlockSingleton INSTANCE; 7 | static { 8 | try { 9 | INSTANCE = new StaticBlockSingleton(); 10 | } catch (Exception e) { 11 | throw new RuntimeException(e); 12 | } 13 | } 14 | public static StaticBlockSingleton getInstance() { 15 | return INSTANCE; 16 | } 17 | private StaticBlockSingleton() { 18 | // ... 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/creational/singleton/singleton.md: -------------------------------------------------------------------------------- 1 | **Intent** 2 | ---------- 3 | Ensure a class only has one instance, and provide a global point of access to it. 4 | 5 | Types 6 | ----- 7 | 1. Normal Singleton 8 | 2. Eager Singleton 9 | 3. Double Lock Singleton 10 | 4. Bill Push Singleton 11 | 5. Static Block Singleton 12 | 6. Enum Based Singleton 13 | 14 | 15 | ![singleton.png](singleton.png) 16 | 17 | most commonly used design pattern 18 | 19 | Applications 20 | 1. when managing access to a resource which is shared by the entire application 21 | 2. Singleton pattern is used for logging, drivers objects, caching, and thread pool 22 | 3. **Real World Example** : sharing a single washing machine among all the residents in a hotel or sharing a single appliance like refrigerator among all the family members -------------------------------------------------------------------------------- /src/creational/singleton/singleton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/creational/singleton/singleton.png -------------------------------------------------------------------------------- /src/structural/Structural Design Patterns.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/Structural Design Patterns.md -------------------------------------------------------------------------------- /src/structural/adaptor/adaptor.md: -------------------------------------------------------------------------------- 1 | **Intent** 2 | ------ 3 | *Adapter is a behavioral design pattern that allows objects with incompatible interfaces to collaborate.* 4 | 5 | 6 | *Here I am Implementing Adaptor to call vendor api's from client. Where vendor accepts request as XML 7 | and Client send request as JSON. both are incompatible we used adaptor in between to convert client JSON 8 | to XML and call to Vendor API and take the response and return to Client incompatible* 9 | 10 | **Adapters are two Types** 11 | 1. Object Adapter and 12 | 2. Class Adapter 13 | 14 | In this example we used Object Adapter. To use Class Adapter we required Multiple Inheritance and java doesn't supports 15 | 16 | Also using Class Adapter is violating principle of "Use composition Over Inheritance" 17 | 18 | ![adaptor](adaptor_sketch.png) 19 | 20 | ![img.png](adaptor.png) 21 | 22 | Try This. 23 | --------- 24 | We have different data sources [JPA, Mongo, Cassandra, ...] 25 | 26 | Try to create different repositories and without changing any client code. what ever data store client 27 | wants your code should automatically support that without changing business logic and repository logic Changing 28 | 29 | _Hint:_ Try To Use Adaptor and Factory Patterns 30 | 31 | Will discuss when we do Project on Design Patterns -------------------------------------------------------------------------------- /src/structural/adaptor/adaptor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/adaptor/adaptor.png -------------------------------------------------------------------------------- /src/structural/adaptor/adaptor_sketch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/adaptor/adaptor_sketch.png -------------------------------------------------------------------------------- /src/structural/adaptor/objectadaptor/Adaptor.java: -------------------------------------------------------------------------------- 1 | package structural.adaptor.objectadaptor; 2 | 3 | import structural.adaptor.objectadaptor.client.ClientInterface; 4 | import structural.adaptor.objectadaptor.client.JSONObject; 5 | import structural.adaptor.objectadaptor.vendor.XMLVendor; 6 | import structural.adaptor.objectadaptor.vendor.XMLObject; 7 | 8 | // Adaptor Has Adaptee ( Incompatible with client Interface ) 9 | public class Adaptor implements ClientInterface { 10 | 11 | XMLVendor vendor; 12 | 13 | public Adaptor(XMLVendor vendor){ 14 | this.vendor = vendor; 15 | } 16 | 17 | @Override 18 | public String serveRequest(JSONObject request) { 19 | // Convert JSONObject to XMLObject ( vendor accepts) 20 | XMLObject xmlObject = new XMLObject(request.getRequestId(), request.getMetadata()); 21 | System.out.println("Vendor call made"); 22 | return vendor.serveRequest(xmlObject); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/structural/adaptor/objectadaptor/Driver.java: -------------------------------------------------------------------------------- 1 | package structural.adaptor.objectadaptor; 2 | 3 | import structural.adaptor.objectadaptor.client.Client; 4 | import structural.adaptor.objectadaptor.vendor.XMLVendor; 5 | 6 | public class Driver { 7 | public static void main(String[] args) { 8 | Client client = new Client(new Adaptor(new XMLVendor())); 9 | System.out.println(client.apiCallToVendor()); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/structural/adaptor/objectadaptor/client/Client.java: -------------------------------------------------------------------------------- 1 | package structural.adaptor.objectadaptor.client; 2 | 3 | public class Client { 4 | 5 | ClientInterface clientInterface; 6 | 7 | public Client(ClientInterface clientInterface){ 8 | this.clientInterface = clientInterface; 9 | } 10 | 11 | public String apiCallToVendor(){ 12 | JSONObject jsonObject = new JSONObject("123","MetaData"); 13 | String s = clientInterface.serveRequest(jsonObject); 14 | return s; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/structural/adaptor/objectadaptor/client/ClientInterface.java: -------------------------------------------------------------------------------- 1 | package structural.adaptor.objectadaptor.client; 2 | 3 | public interface ClientInterface { 4 | String serveRequest(JSONObject request); 5 | } 6 | -------------------------------------------------------------------------------- /src/structural/adaptor/objectadaptor/client/JSONObject.java: -------------------------------------------------------------------------------- 1 | package structural.adaptor.objectadaptor.client; 2 | 3 | public class JSONObject { 4 | private String requestId; 5 | private String metadata; 6 | 7 | public JSONObject(String requestId, String metadata) { 8 | this.requestId = requestId; 9 | this.metadata = metadata; 10 | } 11 | 12 | public String getRequestId() { 13 | return requestId; 14 | } 15 | 16 | public String getMetadata() { 17 | return metadata; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/structural/adaptor/objectadaptor/vendor/XMLObject.java: -------------------------------------------------------------------------------- 1 | package structural.adaptor.objectadaptor.vendor; 2 | 3 | public class XMLObject { 4 | private String requestId; 5 | private String metadata; 6 | 7 | public XMLObject(String requestId, String metadata) { 8 | this.requestId = requestId; 9 | this.metadata = metadata; 10 | } 11 | 12 | public String getRequestId() { 13 | return requestId; 14 | } 15 | 16 | public String getMetadata() { 17 | return metadata; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/structural/adaptor/objectadaptor/vendor/XMLVendor.java: -------------------------------------------------------------------------------- 1 | package structural.adaptor.objectadaptor.vendor; 2 | 3 | public class XMLVendor { 4 | 5 | public String serveRequest(XMLObject xmlObject){ 6 | return (xmlObject.getRequestId() + " " + xmlObject.getMetadata() + " Success"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/structural/bridge/Driver.java: -------------------------------------------------------------------------------- 1 | package structural.bridge; 2 | 3 | 4 | import structural.bridge.babstraction.Circle; 5 | import structural.bridge.babstraction.Rectangle; 6 | import structural.bridge.babstraction.Shape; 7 | import structural.bridge.babstraction.Triangle; 8 | import structural.bridge.binterface.BlackColor; 9 | import structural.bridge.binterface.RedColor; 10 | import structural.bridge.binterface.WhiteColor; 11 | 12 | public class Driver { 13 | public static void main(String[] args) { 14 | // Shape has Color -> according to bridge Definition 15 | Shape rectangleShape = new Rectangle(new BlackColor()); 16 | rectangleShape.paint(); 17 | 18 | Shape circleShape = new Circle(new RedColor()); 19 | circleShape.paint(); 20 | 21 | Shape circleWhitShape = new Circle(new WhiteColor()); 22 | circleWhitShape.paint(); 23 | 24 | Shape triangleShape = new Triangle(new BlackColor()); 25 | triangleShape.paint(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/structural/bridge/babstraction/Circle.java: -------------------------------------------------------------------------------- 1 | package structural.bridge.babstraction; 2 | 3 | import structural.bridge.binterface.Color; 4 | 5 | public class Circle extends Shape{ 6 | 7 | public Circle(Color color) { 8 | super(color); 9 | } 10 | 11 | @Override 12 | public void paint() { 13 | System.out.println("Circle Painted: "+color.getColor()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/structural/bridge/babstraction/Rectangle.java: -------------------------------------------------------------------------------- 1 | package structural.bridge.babstraction; 2 | 3 | import structural.bridge.binterface.Color; 4 | 5 | public class Rectangle extends Shape { 6 | public Rectangle(Color color) { 7 | super(color); 8 | } 9 | 10 | @Override 11 | public void paint() { 12 | System.out.println("Rectangle Painted: "+color.getColor()); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/structural/bridge/babstraction/Shape.java: -------------------------------------------------------------------------------- 1 | package structural.bridge.babstraction; 2 | 3 | import structural.bridge.binterface.Color; 4 | 5 | public abstract class Shape { 6 | 7 | Color color; 8 | public Shape(Color color){ 9 | this.color = color; 10 | } 11 | 12 | public abstract void paint(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/structural/bridge/babstraction/Triangle.java: -------------------------------------------------------------------------------- 1 | package structural.bridge.babstraction; 2 | 3 | import structural.bridge.binterface.Color; 4 | 5 | public class Triangle extends Shape { 6 | 7 | public Triangle(Color color) { 8 | super(color); 9 | } 10 | 11 | @Override 12 | public void paint() { 13 | System.out.println("Triangle Painted: "+color.getColor()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/structural/bridge/binterface/BlackColor.java: -------------------------------------------------------------------------------- 1 | package structural.bridge.binterface; 2 | 3 | public class BlackColor implements Color{ 4 | @Override 5 | public String getColor() { 6 | return "BLACK"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/structural/bridge/binterface/Color.java: -------------------------------------------------------------------------------- 1 | package structural.bridge.binterface; 2 | 3 | public interface Color { 4 | String getColor(); 5 | } 6 | -------------------------------------------------------------------------------- /src/structural/bridge/binterface/RedColor.java: -------------------------------------------------------------------------------- 1 | package structural.bridge.binterface; 2 | 3 | public class RedColor implements Color{ 4 | @Override 5 | public String getColor() { 6 | return "RED"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/structural/bridge/binterface/WhiteColor.java: -------------------------------------------------------------------------------- 1 | package structural.bridge.binterface; 2 | 3 | public class WhiteColor implements Color{ 4 | @Override 5 | public String getColor() { 6 | return "WHITE"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/structural/bridge/bridge.md: -------------------------------------------------------------------------------- 1 | Intent 2 | ------- 3 | Decouple an abstraction from its implementation so that the two can vary independently. 4 | 5 | _This means to create a bridge interface that uses OOP principles to separate out responsibilities into different abstract classes._ 6 | 7 | ![img.png](img.png) 8 | 9 | **Another Example** 10 | 11 | _Think of a car manufacturing company. The company wants to make both sports cars and family cars. Both types of cars have engines and wheels, but the way they are designed and the features they have are different. The company can use the Bridge Design Pattern to separate the engine and wheel components from the actual car design._ 12 | 13 | _So, the engine and wheel components are the abstractions, and the actual car design (sports car or family car) is the implementation. This way, the company can change the engine or wheel components independently without affecting the sports car or family car design and vice versa. This helps the company to be more flexible and adapt to changing market needs quickly._ 14 | 15 | ![bridge_car](bridge_car.png) 16 | 17 | **Applicability** 18 | ------------------- 19 | Use the Bridge pattern when 20 | * you want to avoid a permanent binding between an abstraction and its implementation. This might be the case,for example,when the implementation 21 | must be selected or switched at run-time. 22 | * Both the abstractions and their implementations should be extensible by 23 | subclassing. In this case, the Bridge pattern lets you combine the different 24 | abstractions and implementations and extend them independently. 25 | * changes in the implementation of an abstraction should have no impact on 26 | clients; that is, their code should not have to be recompiled -------------------------------------------------------------------------------- /src/structural/bridge/bridge_car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/bridge/bridge_car.png -------------------------------------------------------------------------------- /src/structural/bridge/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/bridge/img.png -------------------------------------------------------------------------------- /src/structural/composite/Ceo.java: -------------------------------------------------------------------------------- 1 | package structural.composite; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Ceo implements Employee { 7 | 8 | private final String name; 9 | private final int empId; 10 | private final Position position; 11 | 12 | private final List reportingEmployees; 13 | 14 | public Ceo(int empId, String name, Position position) { 15 | this.empId = empId; 16 | this.name = name; 17 | this.position = position; 18 | this.reportingEmployees = new ArrayList<>(); 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public int getEmpId() { 26 | return empId; 27 | } 28 | 29 | public Position getPosition() { 30 | return position; 31 | } 32 | 33 | @Override 34 | public void printEmployeeDetails() { 35 | System.out.println(this); 36 | } 37 | 38 | public void addEmployee(Employee emp) { 39 | reportingEmployees.add(emp); 40 | } 41 | 42 | public void removeEmployee(Employee emp) { 43 | reportingEmployees.remove(emp); 44 | } 45 | 46 | 47 | @Override 48 | public String toString() { 49 | return "Ceo{" + 50 | "name='" + name + '\'' + 51 | ", empId=" + empId + 52 | ", position=" + position + 53 | ", reportingEmployees=" + reportingEmployees + 54 | '}'; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/structural/composite/Developer.java: -------------------------------------------------------------------------------- 1 | package structural.composite; 2 | 3 | public class Developer implements Employee{ 4 | 5 | private final String name; 6 | private final int empId; 7 | private final Position position; 8 | 9 | public Developer(int empId, String name, Position position) { 10 | this.empId = empId; 11 | this.name = name; 12 | this.position = position; 13 | } 14 | 15 | public String getName() { 16 | return name; 17 | } 18 | 19 | public int getEmpId() { 20 | return empId; 21 | } 22 | 23 | public Position getPosition() { 24 | return position; 25 | } 26 | 27 | @Override 28 | public void printEmployeeDetails() { 29 | System.out.println(toString()); 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "Developer {" + 35 | "name='" + name + '\'' + 36 | ", empId=" + empId + 37 | ", position='" + position + '\'' + 38 | '}'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/structural/composite/Driver.java: -------------------------------------------------------------------------------- 1 | package structural.composite; 2 | 3 | /* Acts as Client */ 4 | public class Driver { 5 | public static void main(String[] args) { 6 | 7 | Developer dev1 = new Developer(1, "Mark", Position.DEVELOPER); 8 | Developer dev2 = new Developer(2, "Elon", Position.SENIOR_DEVELOPER); 9 | 10 | Manager man1 = new Manager(200, "Sundar Pichai", Position.MANAGER); 11 | Manager man2 = new Manager(201, "Satya Nadal ", Position.MANAGER); 12 | 13 | ProductOwner p1 = new ProductOwner(10, "Bill Gates", Position.PRODUCT_OWNER); 14 | ProductOwner p2 = new ProductOwner(11, "Steve Jobs", Position.PRODUCT_OWNER); 15 | 16 | 17 | Ceo c = new Ceo(1, "Lava Kumar",Position.CEO); 18 | 19 | 20 | man1.addEmployee(dev1); 21 | man2.addEmployee(dev2); 22 | 23 | p1.addEmployee(man1); 24 | p2.addEmployee(man2); 25 | 26 | c.addEmployee(p1); 27 | c.addEmployee(p2); 28 | 29 | 30 | c.printEmployeeDetails(); 31 | 32 | dev1.printEmployeeDetails(); 33 | 34 | 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/structural/composite/Driver2.java: -------------------------------------------------------------------------------- 1 | package structural.composite; 2 | 3 | public class Driver2 { 4 | public static void main(String[] args) { 5 | Developer dev1 = new Developer(1, "Mark", Position.DEVELOPER); 6 | Developer dev2 = new Developer(2, "Elon", Position.SENIOR_DEVELOPER); 7 | 8 | Employeer man1 = new Employeer(200, "Sundar Pichai", Position.MANAGER); 9 | Employeer man2 = new Employeer(201, "Satya Nadal ", Position.MANAGER); 10 | 11 | Employeer p1 = new Employeer(10, "Bill Gates", Position.PRODUCT_OWNER); 12 | Employeer p2 = new Employeer(11, "Steve Jobs", Position.PRODUCT_OWNER); 13 | 14 | 15 | Employeer c = new Employeer(1, "Lava Kumar",Position.CEO); 16 | 17 | man1.addEmployee(dev1); 18 | man2.addEmployee(dev2); 19 | 20 | p1.addEmployee(man1); 21 | p2.addEmployee(man2); 22 | 23 | c.addEmployee(p1); 24 | c.addEmployee(p2); 25 | 26 | 27 | c.printEmployeeDetails(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/structural/composite/Employee.java: -------------------------------------------------------------------------------- 1 | package structural.composite; 2 | 3 | public interface Employee { 4 | void printEmployeeDetails(); 5 | } 6 | -------------------------------------------------------------------------------- /src/structural/composite/Employeer.java: -------------------------------------------------------------------------------- 1 | package structural.composite; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Employeer implements Employee { 7 | 8 | private final String name; 9 | private final int empId; 10 | private final Position position; 11 | private final List reportingEmployees; 12 | 13 | public Employeer(int empId, String name, Position position) { 14 | this.empId = empId; 15 | this.name = name; 16 | this.position = position; 17 | reportingEmployees = new ArrayList<>(); 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public int getEmpId() { 25 | return empId; 26 | } 27 | 28 | public Position getPosition() { 29 | return position; 30 | } 31 | 32 | @Override 33 | public void printEmployeeDetails() { 34 | System.out.println(toString()); 35 | } 36 | 37 | public void addEmployee(Employee emp) { 38 | reportingEmployees.add(emp); 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return position.toString()+" {" + 44 | "name='" + name + '\''+ 45 | ", empId=" + empId + 46 | ", position='" + position + '\n' + 47 | ", reportingEmployees=" + reportingEmployees + '\n'+ 48 | '}'; 49 | } 50 | } -------------------------------------------------------------------------------- /src/structural/composite/Manager.java: -------------------------------------------------------------------------------- 1 | package structural.composite; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Manager implements Employee{ 7 | 8 | private final String name; 9 | private final int empId; 10 | private final Position position; 11 | 12 | private final List reportingEmployees; 13 | 14 | public Manager(int empId, String name, Position position) { 15 | this.empId = empId; 16 | this.name = name; 17 | this.position = position; 18 | this.reportingEmployees = new ArrayList<>(); 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public int getEmpId() { 26 | return empId; 27 | } 28 | 29 | public Position getPosition() { 30 | return position; 31 | } 32 | 33 | @Override 34 | public void printEmployeeDetails() { 35 | System.out.println(this); 36 | } 37 | 38 | public void addEmployee(Employee emp) { 39 | reportingEmployees.add(emp); 40 | } 41 | 42 | public void removeEmployee(Employee emp) { 43 | reportingEmployees.remove(emp); 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return "Manager {" + 49 | "name='" + name + '\'' + 50 | ", empId=" + empId + 51 | ", position=" + position + 52 | ", reportingEmployees=" + reportingEmployees + 53 | '}'; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/structural/composite/Position.java: -------------------------------------------------------------------------------- 1 | package structural.composite; 2 | 3 | public enum Position { 4 | CEO, 5 | PRODUCT_OWNER, 6 | MANAGER, 7 | DEVELOPER, 8 | SENIOR_DEVELOPER; 9 | } 10 | -------------------------------------------------------------------------------- /src/structural/composite/ProductOwner.java: -------------------------------------------------------------------------------- 1 | package structural.composite; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class ProductOwner implements Employee{ 7 | 8 | private final String name; 9 | private final int empId; 10 | private final Position position; 11 | 12 | private final List reportingEmployees; 13 | 14 | public ProductOwner(int empId, String name, Position position) { 15 | this.empId = empId; 16 | this.name = name; 17 | this.position = position; 18 | this.reportingEmployees = new ArrayList<>(); 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public int getEmpId() { 26 | return empId; 27 | } 28 | 29 | public Position getPosition() { 30 | return position; 31 | } 32 | 33 | @Override 34 | public void printEmployeeDetails() { 35 | System.out.println(this); 36 | } 37 | 38 | public void addEmployee(Employee emp) { 39 | reportingEmployees.add(emp); 40 | } 41 | 42 | public void removeEmployee(Employee emp) { 43 | reportingEmployees.remove(emp); 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return "ProductOwner {" + 49 | "name='" + name + '\'' + 50 | ", empId=" + empId + 51 | ", position=" + position + 52 | ", reportingEmployees=" + reportingEmployees + 53 | '}'; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/structural/composite/composite.md: -------------------------------------------------------------------------------- 1 | Intent 2 | ------ 3 | *Composite is a behavioral design pattern that lets you compose objects into tree structures and 4 | then work with these structures as if they were individual objects.* 5 | 6 | Simply its object made up of number of objects 7 | 8 | ![composite.png](composite.png) 9 | 10 | ![composite](composite_org.png) 11 | 12 | Let's see the 4 elements of composite pattern. 13 | 14 | 1) **Component** 15 | Declares interface for objects in composition. 16 | Implements default behavior for the interface common to all classes as appropriate. 17 | Declares an interface for accessing and managing its child components. 18 | 2) **Leaf** 19 | Represents leaf objects in composition. A leaf has no children. 20 | Defines behavior for primitive objects in the composition. 21 | 3) **Composite** 22 | Defines behavior for components having children. 23 | Stores child component. 24 | Implements child related operations in the component interface. 25 | 4) **Client** 26 | Manipulates objects in the composition through the component interface. 27 | 28 | Example Here: 29 | ------------ 30 | 1. 31 | - Interface : Employee 32 | - Developer : Leaf 33 | - Manager | ProductOwner | CEO : Composite [ contains many nodes ] 34 | - Driver: Client 35 | 2. 36 | - Interface : Employee 37 | - Employer : Leaf and Composite 38 | - Driver: Client 39 | -------------------------------------------------------------------------------- /src/structural/composite/composite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/composite/composite.png -------------------------------------------------------------------------------- /src/structural/composite/composite_org.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/composite/composite_org.png -------------------------------------------------------------------------------- /src/structural/decorator/BasicCar.java: -------------------------------------------------------------------------------- 1 | package structural.decorator; 2 | 3 | public class BasicCar implements Car{ 4 | @Override 5 | public void assemble() { 6 | System.out.print(" Basic Car -"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/structural/decorator/Car.java: -------------------------------------------------------------------------------- 1 | package structural.decorator; 2 | 3 | public interface Car { 4 | void assemble(); 5 | } 6 | -------------------------------------------------------------------------------- /src/structural/decorator/CarDecorator.java: -------------------------------------------------------------------------------- 1 | package structural.decorator; 2 | 3 | public class CarDecorator implements Car { 4 | // Composition Over Inheritance 5 | 6 | protected Car car; 7 | 8 | public CarDecorator(Car car){ 9 | this.car = car; 10 | } 11 | 12 | @Override 13 | public void assemble() { 14 | car.assemble(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/structural/decorator/Driver.java: -------------------------------------------------------------------------------- 1 | package structural.decorator; 2 | 3 | public class Driver { 4 | public static void main(String[] args) { 5 | Car car = new BasicCar(); 6 | car.assemble(); 7 | System.out.println(); 8 | 9 | Car luxuryCar = new LuxuryCar(new BasicCar()); 10 | luxuryCar.assemble(); 11 | System.out.println(); 12 | 13 | Car luxurySportsCar = new LuxuryCar(new SportsCar(new BasicCar())); 14 | luxurySportsCar.assemble(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/structural/decorator/LuxuryCar.java: -------------------------------------------------------------------------------- 1 | package structural.decorator; 2 | 3 | public class LuxuryCar extends CarDecorator { 4 | 5 | public LuxuryCar(Car car) { 6 | super(car); 7 | } 8 | 9 | @Override 10 | public void assemble() { 11 | super.assemble(); 12 | System.out.print(" Added Features of Luxury Car "); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/structural/decorator/SportsCar.java: -------------------------------------------------------------------------------- 1 | package structural.decorator; 2 | 3 | public class SportsCar extends CarDecorator{ 4 | 5 | public SportsCar(Car car) { 6 | super(car); 7 | } 8 | 9 | @Override 10 | public void assemble() { 11 | super.assemble(); 12 | System.out.print(" Added Features of Sports Car "); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/structural/decorator/decorator.md: -------------------------------------------------------------------------------- 1 | Intent 2 | ----- 3 | *Attach additional responsibilities to an object dynamically. Decorators provide a 4 | flexible alternative to subclassing for extending functionality* 5 | 6 | Here we are implementing Car Decorator 7 | 8 | _(How can we add functionality of a simple basic car to sports car, luxury car etc)_ 9 | 10 | ![decorator.png](decorator.png) -------------------------------------------------------------------------------- /src/structural/decorator/decorator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/decorator/decorator.png -------------------------------------------------------------------------------- /src/structural/facade/AudioMixer.java: -------------------------------------------------------------------------------- 1 | package structural.facade; 2 | 3 | import java.io.File; 4 | 5 | public class AudioMixer { 6 | 7 | public File fix(File desFile){ 8 | return desFile; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/structural/facade/BitrateReader.java: -------------------------------------------------------------------------------- 1 | package structural.facade; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileNotFoundException; 6 | import java.io.FileReader; 7 | 8 | public class BitrateReader { 9 | 10 | public static BufferedReader read(String filename, File sourceCodec) throws FileNotFoundException { 11 | return new BufferedReader(new FileReader(sourceCodec)); 12 | } 13 | 14 | public static File convert(BufferedReader buffer, CompressionCodec destinationCodec){ 15 | return new File("result_file."+destinationCodec.getType()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/structural/facade/CodecFactory.java: -------------------------------------------------------------------------------- 1 | package structural.facade; 2 | 3 | import java.io.File; 4 | 5 | public class CodecFactory { 6 | 7 | public static File extract(VideoFile file){ 8 | return new File("src/structural/facade/codec_file.ogg"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/structural/facade/CompressionCodec.java: -------------------------------------------------------------------------------- 1 | package structural.facade; 2 | 3 | public interface CompressionCodec { 4 | 5 | String getType(); 6 | } 7 | -------------------------------------------------------------------------------- /src/structural/facade/MPEG4CompressionCodec.java: -------------------------------------------------------------------------------- 1 | package structural.facade; 2 | 3 | public class MPEG4CompressionCodec implements CompressionCodec{ 4 | @Override 5 | public String getType() { 6 | return "mp4"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/structural/facade/OggCompressionCodec.java: -------------------------------------------------------------------------------- 1 | package structural.facade; 2 | 3 | public class OggCompressionCodec implements CompressionCodec{ 4 | 5 | @Override 6 | public String getType() { 7 | return "ogg"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/structural/facade/VideoFile.java: -------------------------------------------------------------------------------- 1 | package structural.facade; 2 | 3 | public class VideoFile { 4 | String fileName; 5 | public VideoFile(String fileName){ 6 | this.fileName = fileName; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/structural/facade/codec_file.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/facade/codec_file.ogg -------------------------------------------------------------------------------- /src/structural/facade/facade.md: -------------------------------------------------------------------------------- 1 | Intent: 2 | ------- 3 | *Facade is a behavioral design pattern that provides a simplified interface to a library, a framework, or any 4 | other complex set of classes.* 5 | 1. It encapsulates a complex subsystem behind a simple interface. It hides much of the complexity and makes the subsystem easy to use. 6 | 2. It decouples a client implementation from the complex subsystem 7 | 8 | ![img.png](facade.png) 9 | 10 | ![facade](facde_exp.png) 11 | 12 | **Applicability** 13 | -------------- 14 | Use the Facade pattern when 15 | * *you want to provide a simple interface to a complex subsystem. Subsystems 16 | often get more complex as they evolve. Most patterns, when applied, result 17 | in more and smaller classes. This makes the subsystem more reusable and 18 | easier to customize, but it also becomes harder to use for clients that don't 19 | need to customize it. A facade can provide a simple default view of the 20 | subsystem that is good enough for most clients. Only clients needing more 21 | customizable will need to look beyond the facade.* 22 | * *there are many dependencies between clients and the implementation classes 23 | of an abstraction.Introduce a facade to decouple the subsystem from clients 24 | and other subsystems, thereby promoting subsystem independence and 25 | portability* 26 | * *you want to layer your subsystems. Use a facade to define an entry point to 27 | each subsystem level. If subsystems are dependent, then you can simplify 28 | the dependencies between them by making them communicate with each 29 | other solely through their facades* -------------------------------------------------------------------------------- /src/structural/facade/facade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/facade/facade.png -------------------------------------------------------------------------------- /src/structural/facade/facde_exp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/facade/facde_exp.png -------------------------------------------------------------------------------- /src/structural/facade/withfacade/Client.java: -------------------------------------------------------------------------------- 1 | package structural.facade.withfacade; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | 6 | public class Client { 7 | public static void main(String[] args) throws FileNotFoundException { 8 | VideoConverterFacade videoConverterFacade = new VideoConverterFacade(); 9 | File mp4 = videoConverterFacade.convert("latest-move.ogg", "mp4"); 10 | System.out.println("Converted File Stored in: "+mp4.getName()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/structural/facade/withfacade/VideoConverterFacade.java: -------------------------------------------------------------------------------- 1 | package structural.facade.withfacade; 2 | 3 | import structural.facade.AudioMixer; 4 | import structural.facade.BitrateReader; 5 | import structural.facade.CodecFactory; 6 | import structural.facade.CompressionCodec; 7 | import structural.facade.MPEG4CompressionCodec; 8 | import structural.facade.OggCompressionCodec; 9 | import structural.facade.VideoFile; 10 | 11 | import java.io.BufferedReader; 12 | import java.io.File; 13 | import java.io.FileNotFoundException; 14 | 15 | public class VideoConverterFacade { 16 | 17 | VideoConverterFacade(){ 18 | 19 | } 20 | 21 | public File convert(String filename, String format) throws FileNotFoundException { 22 | 23 | VideoFile file = new VideoFile(filename); 24 | File sourceCodec = CodecFactory.extract(file); 25 | CompressionCodec destinationCodec = null; 26 | if (format.equals("mp4")) 27 | destinationCodec = new MPEG4CompressionCodec(); 28 | else 29 | destinationCodec = new OggCompressionCodec(); 30 | 31 | BufferedReader buffer = BitrateReader.read(filename, sourceCodec); 32 | File desFile = BitrateReader.convert(buffer, destinationCodec); 33 | File result = (new AudioMixer()).fix(desFile); 34 | return result; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/structural/facade/withoutfacade/Client.java: -------------------------------------------------------------------------------- 1 | package structural.facade.withoutfacade; 2 | 3 | import structural.facade.AudioMixer; 4 | import structural.facade.BitrateReader; 5 | import structural.facade.CodecFactory; 6 | import structural.facade.CompressionCodec; 7 | import structural.facade.MPEG4CompressionCodec; 8 | import structural.facade.OggCompressionCodec; 9 | import structural.facade.VideoFile; 10 | 11 | import java.io.BufferedReader; 12 | import java.io.File; 13 | import java.io.FileNotFoundException; 14 | 15 | public class Client { 16 | /* without Facade Client need to manage all the subs systems overhead */ 17 | public static void main(String[] args) throws FileNotFoundException { 18 | String filename = "latest-move.ogg"; 19 | String format = "mp4"; 20 | VideoFile file = new VideoFile(filename); 21 | File sourceCodec = CodecFactory.extract(file); 22 | CompressionCodec destinationCodec = null; 23 | if (format.equals("mp4")) 24 | destinationCodec = new MPEG4CompressionCodec(); 25 | else 26 | destinationCodec = new OggCompressionCodec(); 27 | 28 | BufferedReader buffer = BitrateReader.read(filename, sourceCodec); 29 | File desFile = BitrateReader.convert(buffer, destinationCodec); 30 | File result = (new AudioMixer()).fix(desFile); 31 | System.out.println(result); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/structural/flyweight/Car.java: -------------------------------------------------------------------------------- 1 | package structural.flyweight; 2 | 3 | public abstract class Car { 4 | /*Intrinsic state stored and shared in the Flyweight object*/ 5 | String name; 6 | int speed; 7 | int horsePower; 8 | 9 | public Car(String name, int speed, int horsePower) { 10 | this.name = name; 11 | this.speed = speed; 12 | this.horsePower = horsePower; 13 | } 14 | 15 | /* Extrinsic state is stored or computed by client objects, and passed to the Flyweight.*/ 16 | abstract void moveCar(int currentX, int currentY, int newX ,int newY); 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/structural/flyweight/CarFactory.java: -------------------------------------------------------------------------------- 1 | package structural.flyweight; 2 | 3 | import structural.flyweight.exception.ObjectCreationException; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | public class CarFactory { 9 | private static final Map flyweights = new HashMap<>(); 10 | 11 | public static Car getRaceCar(CarType type) { 12 | if(flyweights.containsKey(type)){ 13 | return flyweights.get(type); 14 | } 15 | Car car; 16 | switch (type){ 17 | case McLearn: car = new McLearnCar("McLearn", 150,1000); 18 | flyweights.put(type,car); 19 | break; 20 | case PORSCHE: car = new PorscheCar("PORSCHE", 250,1500); 21 | flyweights.put(type,car); 22 | break; 23 | default: throw new ObjectCreationException("Object Creation Failed"); 24 | } 25 | return car; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/structural/flyweight/CarType.java: -------------------------------------------------------------------------------- 1 | package structural.flyweight; 2 | 3 | public enum CarType { 4 | PORSCHE, 5 | McLearn 6 | } 7 | -------------------------------------------------------------------------------- /src/structural/flyweight/Driver.java: -------------------------------------------------------------------------------- 1 | package structural.flyweight; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | import java.util.Random; 7 | 8 | public class Driver { 9 | public static void main(String[] args) { 10 | Random random = new Random(); 11 | List carTypes = Arrays.asList(CarType.McLearn, CarType.McLearn, CarType.PORSCHE, CarType.PORSCHE); 12 | List cars = new ArrayList<>(); 13 | for(CarType type:carTypes){ 14 | cars.add(CarFactory.getRaceCar(type)); 15 | } 16 | 17 | for(Car car:cars){ 18 | int currentX = random.nextInt(100); 19 | int currentY = random.nextInt(100); 20 | int nextX = random.nextInt(100); 21 | int nextY = random.nextInt(100); 22 | car.moveCar(currentX,currentY,nextX,nextY); 23 | } 24 | System.out.println("Instances Created by McLearn Car "+McLearnCar.numOfInstances); 25 | System.out.println("Instances Created by Porsche Car "+PorscheCar.numOfInstances); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/structural/flyweight/McLearnCar.java: -------------------------------------------------------------------------------- 1 | package structural.flyweight; 2 | 3 | public class McLearnCar extends Car{ 4 | public static int numOfInstances = 0; 5 | public McLearnCar(String name, int speed, int horsePower) { 6 | super(name, speed, horsePower); 7 | numOfInstances++; 8 | } 9 | 10 | @Override 11 | void moveCar(int currentX, int currentY, int newX, int newY) { 12 | System.out.println("Current location of "+this.name+" is X"+currentX + " - Y"+currentY); 13 | System.out.println("New location of "+this.name+" is X"+newX + " - Y"+newY); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/structural/flyweight/PorscheCar.java: -------------------------------------------------------------------------------- 1 | package structural.flyweight; 2 | 3 | public class PorscheCar extends Car{ 4 | public static int numOfInstances = 0; 5 | public PorscheCar(String name, int speed, int horsePower) { 6 | super(name, speed, horsePower); 7 | numOfInstances++; 8 | } 9 | 10 | @Override 11 | void moveCar(int currentX, int currentY, int newX, int newY) { 12 | System.out.println("Current location of "+this.name+" is X"+currentX + " - Y"+currentY); 13 | System.out.println("New location of "+this.name+" is X"+newX + " - Y"+newY); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/structural/flyweight/exception/ObjectCreationException.java: -------------------------------------------------------------------------------- 1 | package structural.flyweight.exception; 2 | 3 | public class ObjectCreationException extends RuntimeException{ 4 | 5 | public ObjectCreationException(String message){ 6 | System.out.println(message+" Object Creation Failed"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/structural/flyweight/flyweight.md: -------------------------------------------------------------------------------- 1 | Intent 2 | ------ 3 | *is a behavioral design pattern that lets you fit more objects into the available amount of RAM 4 | by sharing common parts of state between multiple objects instead of keeping all the data in each object* 5 | 6 | 7 | A flyweight is a shared object that can be used in multiple contexts simultaneously. 8 | The flyweight acts as an independent object in each context—it's indistinguishable from an instance of the object that's not shared. 9 | Flyweights cannot make assumptions about the context in which they operate. 10 | 11 | This allows for a reduction in memory usage and improved overall performance. 12 | 13 | 14 | The key concept here is the distinction between intrinsic and extrinsic state. 15 | 1. Intrinsic state refers to the information that is stored within the shared object, which is common to all objects that use the shared object. This information is usually immutable, meaning it cannot be changed, and is usually shared among many objects to reduce memory usage. 16 | 17 | 2. Extrinsic state, on the other hand, refers to the information that is unique to each individual object and cannot be shared among objects. This information is stored outside of the shared object and is passed as arguments to methods on the shared object when needed. 18 | 19 | 3. In other words, intrinsic state is the information that is stored in the shared object and is common to all objects that use it, while extrinsic state is the information that is unique to each individual object and is stored outside of the shared object. 20 | 21 | 4. By separating the object's state into intrinsic and extrinsic state, the Flyweight Design Pattern allows for a reduction in memory usage and improved performance, as the intrinsic state is shared among multiple objects, while the extrinsic state is stored only once for each individual object. 22 | 23 | 24 | 25 | 26 | 27 | 28 | ![img.png](flyweight.png) 29 | 30 | Implementation: 31 | -------------- 32 | In Flyweight pattern we use a `**HashMap** |(or Any Data Set Which serves as Cache)` that stores reference to the object which have already been created, 33 | every object is associated with a key. Now when a client wants to create an object, he simply has to pass a key associated with it and 34 | if the object has already been created we simply get the reference to that object else it creates a new object and then returns it reference to the client. -------------------------------------------------------------------------------- /src/structural/flyweight/flyweight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/flyweight/flyweight.png -------------------------------------------------------------------------------- /src/structural/proxy/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/proxy/img.png -------------------------------------------------------------------------------- /src/structural/proxy/protection/Driver.java: -------------------------------------------------------------------------------- 1 | package structural.proxy.protection; 2 | 3 | public class Driver { 4 | public static void main(String[] args) { 5 | Internet internet = new ProxyInternet(new RealInternet()); 6 | 7 | try { 8 | internet.connectTo("google.com"); 9 | internet.connectTo("xyz.com"); 10 | }catch (Exception e){ 11 | System.out.println(e.getMessage()); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/structural/proxy/protection/Internet.java: -------------------------------------------------------------------------------- 1 | package structural.proxy.protection; 2 | 3 | public interface Internet { 4 | void connectTo(String serverHost) throws Exception; 5 | } 6 | -------------------------------------------------------------------------------- /src/structural/proxy/protection/Properties.java: -------------------------------------------------------------------------------- 1 | package structural.proxy.protection; 2 | 3 | 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.Stream; 8 | 9 | public class Properties { 10 | public static Set bannedSites = Stream.of("xyz.com", "tamilrockers.com", "torrent.com") 11 | .collect(Collectors.toCollection(HashSet::new)); 12 | } 13 | -------------------------------------------------------------------------------- /src/structural/proxy/protection/ProxyInternet.java: -------------------------------------------------------------------------------- 1 | package structural.proxy.protection; 2 | 3 | public class ProxyInternet implements Internet { 4 | 5 | Internet internet; 6 | public ProxyInternet(Internet internet){ 7 | this.internet = internet; 8 | } 9 | 10 | @Override 11 | public void connectTo(String serverHost) throws Exception { 12 | // get properties 13 | if(Properties.bannedSites.contains(serverHost)){ 14 | throw new Exception("Access Denied to "+serverHost); 15 | } 16 | internet.connectTo(serverHost); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/structural/proxy/protection/RealInternet.java: -------------------------------------------------------------------------------- 1 | package structural.proxy.protection; 2 | 3 | public class RealInternet implements Internet { 4 | 5 | @Override 6 | public void connectTo(String serverHost) throws Exception { 7 | System.out.println("Connected to "+serverHost); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/structural/proxy/proxy.drawio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lavakumarThatisetti/GOFDesignPatterns/d31ed7eae9156661ccc9395a5822157eac93357f/src/structural/proxy/proxy.drawio.png -------------------------------------------------------------------------------- /src/structural/proxy/proxy.md: -------------------------------------------------------------------------------- 1 | Intent 2 | ------ 3 | *Proxy is a behavioral design pattern that lets you provide a substitute or placeholder for another object. 4 | A proxy controls access to the original object, allowing you to perform something either before or after the request gets through to the original object.* 5 | 6 | 3 Ways of Proxy 7 | ---------------- 8 | 1. Remote proxy 9 | 2. Virtual Proxy 10 | 3. Protection Proxy 11 | 12 | Remote Proxy: 13 | -------------- 14 | A remote proxy represents an object located in a different address space, such as a networked server. The proxy acts as a representative of the remote object and handles communication between the local client and the remote object 15 | 16 | ![img.png](img.png) 17 | 18 | Virtual Proxy: 19 | ------------- 20 | The virtual proxy design pattern is used to preserve memory from being allotted to an object that may not be used 21 | in the future. Until the object is not used, a light copy of the object (that contains the required details) 22 | is created and shown to the user. 23 | 1. Creating Object On Demand ( Creating Object When call Check SingleTon Replace in Proxy Class) 24 | 2. Show Minimum Required - (On Demand Show Full Details - We Discussed here) 25 | 3. Acts as a Cache Layer ( Chrome storing recent search data in ur local internal storage) 26 | 27 | Protection proxy: 28 | ----------------- 29 | 1. If an application does not have access to some resource then such proxies will talk to the objects 30 | in applications that have access to that resource and then get the result back. 31 | 2. When we access to website over internet and for some websites which are malicious are usually blocked in some orgs 32 | and workplaces. Here They have implemented protection proxy. The proxy first checks the host you are connecting to, 33 | if it is not part of restricted site list, then it connects to the real internet 34 | 35 | 36 | ![Explanation](proxy.drawio.png) -------------------------------------------------------------------------------- /src/structural/proxy/virtual/Book.java: -------------------------------------------------------------------------------- 1 | package structural.proxy.virtual; 2 | 3 | 4 | public interface Book { 5 | String getName(); 6 | String getAuthor(); 7 | boolean isAvailable(); 8 | void showInfo(); 9 | } 10 | -------------------------------------------------------------------------------- /src/structural/proxy/virtual/Driver.java: -------------------------------------------------------------------------------- 1 | package structural.proxy.virtual; 2 | 3 | /* 4 | If an entire library of books, with all the details about each book, is loaded from a database, it will consume 5 | a lot of RAM, and it is very likely that the user will need to issue or return only one book. 6 | The solution, that uses the virtual proxy design pattern, displays only the name, author, and availability 7 | of the books when a list of them is displayed. When a book is selected, all the remaining details will be fetched from the database and shown to the user. 8 | */ 9 | public class Driver { 10 | 11 | public static void main(String[] args) { 12 | Book harryPotterBook = new OriginalBook("Harry Potter","JK Rowling","description.. The Boy Who lived", 13 | 5, true); 14 | 15 | Book proxyBook = new ProxyBook(harryPotterBook); 16 | 17 | proxyBook.showInfo(); 18 | 19 | ((ProxyBook)proxyBook).click(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/structural/proxy/virtual/OriginalBook.java: -------------------------------------------------------------------------------- 1 | package structural.proxy.virtual; 2 | 3 | public class OriginalBook implements Book { 4 | private String name; 5 | private String author; 6 | private String description; 7 | private int rating; 8 | private boolean available; 9 | 10 | public OriginalBook(String name, String author, String description, int rating, boolean available) { 11 | this.name = name; 12 | this.author = author; 13 | this.description = description; 14 | this.rating = rating; 15 | this.available = available; 16 | } 17 | 18 | @Override 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | @Override 24 | public String getAuthor() { 25 | return author; 26 | } 27 | 28 | @Override 29 | public boolean isAvailable() { 30 | return available; 31 | } 32 | 33 | @Override 34 | public void showInfo() { 35 | String info = toString(); 36 | System.out.println(info); 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "OriginalBook{" + 42 | "name='" + name + '\'' + 43 | ", author='" + author + '\'' + 44 | ", description='" + description + '\'' + 45 | ", rating=" + rating + 46 | ", available=" + available + 47 | '}'; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/structural/proxy/virtual/ProxyBook.java: -------------------------------------------------------------------------------- 1 | package structural.proxy.virtual; 2 | 3 | public class ProxyBook implements Book{ 4 | 5 | Book book; 6 | 7 | public ProxyBook(Book book){ 8 | this.book = book; 9 | } 10 | 11 | 12 | @Override 13 | public String getName() { 14 | return book.getName(); 15 | } 16 | 17 | @Override 18 | public String getAuthor() { 19 | return book.getAuthor(); 20 | } 21 | 22 | @Override 23 | public boolean isAvailable() { 24 | return book.isAvailable(); 25 | } 26 | 27 | @Override 28 | public void showInfo() { 29 | System.out.println("ProxyBook Info{" + 30 | "name='" + book.getName() + '\'' + 31 | ", author='" + book.getAuthor() + '\'' + 32 | ", available=" + book.isAvailable() + 33 | '}'); 34 | } 35 | /* It will call the Original Book and Display all the details */ 36 | public void click(){ 37 | book.showInfo(); 38 | } 39 | 40 | } 41 | --------------------------------------------------------------------------------