├── .idea ├── .gitignore ├── misc.xml ├── modules.xml ├── uiDesigner.xml └── vcs.xml ├── Design-Pattern.iml ├── README.md ├── out └── production │ └── Design-Pattern │ ├── SOLID │ └── OpenClose │ │ ├── Car.class │ │ ├── Truck.class │ │ └── Vehicle.class │ ├── command │ ├── Command.class │ ├── Light.class │ ├── LightOffCommand.class │ ├── LightOnCommand.class │ ├── NoCommand.class │ ├── RemoteControl.class │ ├── RemoteLoader.class │ └── command.md │ ├── decorator │ ├── Beverage.class │ ├── CondimentDecorator.class │ ├── DarkRoast.class │ ├── Espresso.class │ ├── HouseBlend.class │ ├── Milk.class │ ├── Mocha.class │ ├── Soy.class │ ├── StarbuzzCoffee.class │ ├── Whip.class │ ├── decorator.md │ └── decorator.png │ ├── factoryMethod │ ├── CalmPizza.class │ ├── CheesePizza.class │ ├── Demo.class │ ├── FactoryMethod.png │ ├── PepperoniPizza.class │ ├── Pizza.class │ ├── PizzaStore.class │ ├── SimplePizzaFactory.class │ └── factoryMethod.md │ ├── observer │ ├── CurrentConditionsDisplay.class │ ├── DisplalyElement.class │ ├── EventSource.class │ ├── Observer.class │ ├── ResponseHandelerOne.class │ ├── ResponseHandelerTwo.class │ ├── Subject.class │ ├── WeatherData.class │ ├── WeatherStation.class │ └── observer.md │ ├── question3 │ ├── Chair.class │ ├── ChairCreator.class │ ├── CoffeeTable.class │ ├── CoffeeTableCreator.class │ ├── Furniture.class │ ├── FurnitureFactory.class │ ├── Table.class │ └── TableCreator.class │ ├── singleton │ ├── Demo.class │ ├── Singleton.class │ ├── singleton.md │ └── singleton.png │ ├── state │ ├── GreenLight.class │ ├── RedLight.class │ ├── State.class │ ├── TestTrafficSignal.class │ ├── TrafficSystem.class │ ├── YellowLight.class │ ├── state.md │ └── stateMachine.png │ ├── strategy │ ├── Addition.class │ ├── Context.class │ ├── Demo.class │ ├── Multiplication.class │ ├── Strategy.class │ └── Substraction.class │ └── template │ ├── CaffeineBeverage.class │ ├── CaffeineHouse.class │ ├── Coffee.class │ ├── Tea.class │ └── template.md └── src ├── Composition ├── AbstractFile.java ├── CompositeDemo.java ├── Directory.java └── File.java ├── SOLID └── OpenClose │ └── Vehicle.java ├── command ├── Command.java ├── Light.java ├── LightOffCommand.java ├── LightOnCommand.java ├── NoCommand.java ├── RemoteControl.java ├── RemoteLoader.java └── command.md ├── decorator ├── Beverage.java ├── CondimentDecorator.java ├── DarkRoast.java ├── Espresso.java ├── HouseBlend.java ├── Milk.java ├── Mocha.java ├── Soy.java ├── StarbuzzCoffee.java ├── Whip.java ├── decorator.md └── decorator.png ├── factoryMethod ├── CalmPizza.java ├── CheesePizza.java ├── Demo.java ├── FactoryMethod.png ├── PepperoniPizza.java ├── Pizza.java ├── PizzaStore.java ├── SimplePizzaFactory.java └── factoryMethod.md ├── observer ├── CurrentConditionsDisplay.java ├── DisplalyElement.java ├── EventSource.java ├── Observer.java ├── ResponseHandelerOne.java ├── ResponseHandelerTwo.java ├── Subject.java ├── WeatherData.java ├── WeatherStation.java └── observer.md ├── question3 └── Furniture.java ├── singleton ├── Demo.java ├── Singleton.java ├── singleton.md └── singleton.png ├── state ├── GreenLight.java ├── RedLight.java ├── State.java ├── TestTrafficSignal.java ├── TrafficSystem.java ├── TrafficSystemWithoutPattern.java ├── YellowLight.java ├── state.md └── stateMachine.png ├── strategy ├── Addition.java ├── Context.java ├── Demo.java ├── Multiplication.java ├── Strategy.java ├── Substraction.java └── WithoutPattern.java └── template ├── CaffeineBeverage.java ├── CaffeineHouse.java ├── Coffee.java ├── Tea.java ├── template.md └── template.png /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Design-Pattern.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Design-Pattern 2 |
    3 |
  1. Factory Method
  2. 4 |
  3. Decorator
  4. 5 |
  5. Observer
  6. 6 |
  7. Strategy
  8. 7 |
  9. Singleton
  10. 8 |
  11. State
  12. 9 |
  13. Templte
  14. 10 |
  15. Command
  16. 11 |
  17. Composite
  18. 12 |
13 | -------------------------------------------------------------------------------- /out/production/Design-Pattern/SOLID/OpenClose/Car.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/SOLID/OpenClose/Car.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/SOLID/OpenClose/Truck.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/SOLID/OpenClose/Truck.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/SOLID/OpenClose/Vehicle.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/SOLID/OpenClose/Vehicle.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/command/Command.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/command/Command.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/command/Light.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/command/Light.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/command/LightOffCommand.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/command/LightOffCommand.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/command/LightOnCommand.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/command/LightOnCommand.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/command/NoCommand.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/command/NoCommand.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/command/RemoteControl.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/command/RemoteControl.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/command/RemoteLoader.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/command/RemoteLoader.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/command/command.md: -------------------------------------------------------------------------------- 1 | # Command Pattern 2 | 3 |

A request is wrapped under an object as command and passed to invoker object. 4 | Invoker object looks for the appropriate object which can handle this command and passes the command to the corresponding object which executes the command. 5 |

6 | -------------------------------------------------------------------------------- /out/production/Design-Pattern/decorator/Beverage.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/decorator/Beverage.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/decorator/CondimentDecorator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/decorator/CondimentDecorator.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/decorator/DarkRoast.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/decorator/DarkRoast.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/decorator/Espresso.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/decorator/Espresso.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/decorator/HouseBlend.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/decorator/HouseBlend.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/decorator/Milk.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/decorator/Milk.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/decorator/Mocha.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/decorator/Mocha.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/decorator/Soy.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/decorator/Soy.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/decorator/StarbuzzCoffee.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/decorator/StarbuzzCoffee.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/decorator/Whip.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/decorator/Whip.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/decorator/decorator.md: -------------------------------------------------------------------------------- 1 | # Decorator Pattern 2 | 3 | **Decorator Pattern** একজন ইউজারকে একটি অবজেক্টের স্টাকচার পরিবর্তন না করেই নতুন নতুন **functionality** যোগ করার পারমিশন দেয় । 4 | Decorator pattern allows a user to add new functionality to an existing object without altering its structure. 5 | 6 | # একটু ঝামেলা মনে হচ্ছে ? 7 | 8 | চলুন একটা উদাহরণ দিয়ে ব্যপারটা পরিষ্কার করা যাক, আমরা পেয়াজের কথাই ধরতে পারি । মুল পেয়াজের (যেটি আমরা তরকারিতে ব্যবহার করি) উপর স্তরে স্তরে যে খোসা থাকে এই প্রত্যেকটি স্তরকে 9 | আমরা এক একটি নতুন নতুন **ফিচার** ভাবতে পারি । এই খোসার স্তর কিন্তু পেয়াজের স্টাকচারকে পরিবর্তন করেনি। 10 | 11 | # চলুন আমরা একটা কফি সপ দিয়ে ফেলি 12 | 13 |

কিন্তু কফির দাম কিভাবে নির্ধারণ করবো ?

14 | এইটাতো একদন সোজা প্রত্যেক কফির একটা দাম ফিক্সড করে দিলেইতো হছে !!! 15 |

কিন্তু আমাদের কফি সপে ইচ্ছে মতো ফ্লেবার এড করা যায় । এখন প্রত্যেক নতুন নতুন ফ্লেবারের জন্য তো কিন্তু প্রাইস এড করতে হবে ! একন কি করবো ?

16 | 17 | এখনো বেশী ঝামেলার কিছুতো মনে হচ্ছে না! প্রত্যেকবার এক একটা নতুন ফ্লেবারের জন্য মুল কফির সাথে ফ্লেবারের কষ্ট যোগ করে দিলেই ঝামেলা শেষ !!! 18 | 19 | # চলুন একটু ভিজুয়ালাইজ করে ফেলি 20 | 21 | 22 | এখানে আমাদের মুল কফি হচ্ছে **DarkRoast** এটার উপর দুটো ফ্লেবার যোগ করা হয়েছে । প্রথমে **DarkRoast** এর উপর **Mocha** যোগ করা হয়েছে এবং তারপর **Whip** যোগ করা হয়েছে। এবং কফির দাম নির্ধারণের ক্ষেত্রে প্রথমে **DarkRoast** এর সাথে **Mocha** এর দাম যোগ করা হয়েছে, যোগ করার পর যে দাম পাওয়া গেছে তার সাথে **Whip** এর দম যোগ করা হয়েছে । 23 | 24 |

আশা করি আপনাদের ধারনা ক্লিয়ার হয়েছে

25 | 26 | # চলুন এবার ইমপ্লিমেন্টেশনে যাওয়া যাক 27 | 28 | এখন আমাদের কফি সপেতো আমরা জাস্ট একধরনের কফি বিক্রি করবোনা, অনেক ধরনের কফি থাকতে পারে । এবং তাদের দাম ও এক এক কফির এক এক রকম হবে । তাহলে আমরা **Beverage** নামের একটি **Abstract** ক্লাস তৈরি করে ফেলি । এখন আপনার মনে প্রশ্ন জাগতেই পারে **Abstract** ক্লাস কেন ? এর উত্তর হচ্ছে এক এক কফির দাম এক এক ভাবে ক্যালকুলেশন করা হবে, প্রত্যেকের দামতো আর এক হবেনা আর এক ভাবেও ক্যালকুলেশন করা হবেনা । এইজন্য আমরা **cost** মেথডটিকে **abstract** করলাম এখন প্রত্যেক ধরনের কফি এটাকে ইমপ্লিমেন্ট করে নিজেদের মতো দাম ক্যালকুলেশন করবে । 29 | 30 | ```java 31 | 32 | public abstract class Beverage { 33 | String description = "Unknown Beverage"; 34 | 35 | public String getDescription(){ 36 | return description; 37 | } 38 | 39 | public abstract double cost(); 40 | } 41 | 42 | ``` 43 | 44 | # প্রথমে আমরা জাস্ট **DarkRoast**, **Espresso** এবং **HouseBlend** কফি বিক্রি করবো 45 | 46 | ```java 47 | 48 | public class DarkRoast extends Beverage { 49 | public DarkRoast() { 50 | description = "Dark Roast Coffee"; 51 | } 52 | 53 | public double cost() { 54 | return .99; 55 | } 56 | } 57 | 58 | ``` 59 | 60 | ```java 61 | 62 | public class HouseBlend extends Beverage{ 63 | public HouseBlend() { 64 | description = "House Blend Coffee"; 65 | } 66 | 67 | @Override 68 | public double cost() { 69 | return 0.89; 70 | } 71 | } 72 | 73 | ``` 74 | 75 | ```java 76 | 77 | public class Espresso extends Beverage{ 78 | 79 | public Espresso() { 80 | description = "Espresso"; 81 | } 82 | 83 | @Override 84 | public double cost() { 85 | return 1.99; 86 | } 87 | } 88 | 89 | ``` 90 | 91 | # এবার ফ্লেবারে আসা যাক 92 | 93 | ```java 94 | public abstract class CondimentDecorator extends Beverage{ 95 | Beverage beverage; 96 | public abstract String getDescription(); 97 | } 98 | ``` 99 | 100 |

আমরা কেন **Beverage** ক্লাসকে **extend** করলাম ?

101 | কারণ, আমরা **Beverage** এর স্টাকচার পরিবর্তন না করেই, তার উপর লেয়ার এড করতে চাই। আমাদের যেহেতু অনেক ধরনের ফ্লেবার থাকবে পারে তাই আমরা এখনেও **getDescription** কে **abstract** রাখলাম এবং **Beverage** কে extend করে যে abstract **cost** মেথড পেলাম তাকেও ইমপ্লিমেন্ট করলাম না, এক এক ধরনের ফ্লেবার **CondimentDecorator** ক্লাসকে extend করে এগুলো নিজেকের মতো ইমপ্লিমেন্ট করে নিবে। 102 | 103 | ```java 104 | public class Mocha extends CondimentDecorator { 105 | public Mocha(Beverage beverage) { 106 | this.beverage = beverage; 107 | } 108 | 109 | public String getDescription() { 110 | return beverage.getDescription() + ", Mocha"; 111 | } 112 | 113 | public double cost() { 114 | return .20 + beverage.cost(); 115 | } 116 | } 117 | ``` 118 | 119 | ```java 120 | public class Soy extends CondimentDecorator { 121 | public Soy(Beverage beverage) { 122 | this.beverage = beverage; 123 | } 124 | 125 | public String getDescription() { 126 | return beverage.getDescription() + ", Soy"; 127 | } 128 | 129 | public double cost() { 130 | return .15 + beverage.cost(); 131 | } 132 | } 133 | ``` 134 | 135 | ```java 136 | public class Whip extends CondimentDecorator { 137 | public Whip(Beverage beverage) { 138 | this.beverage = beverage; 139 | } 140 | 141 | public String getDescription() { 142 | return beverage.getDescription() + ", Whip"; 143 | } 144 | 145 | public double cost() { 146 | return .10 + beverage.cost(); 147 | } 148 | } 149 | ``` 150 | 151 | # ঝামেলা শেষ !!! চলুন এবার কফি বাননো যাক 152 | 153 | ```java 154 | public class StarbuzzCoffee { 155 | 156 | public static void main(String args[]) { 157 | Beverage beverage = new Espresso(); 158 | System.out.println(beverage.getDescription() 159 | + " $" + beverage.cost()); 160 | 161 | Beverage beverage2 = new DarkRoast(); 162 | beverage2 = new Mocha(beverage2); 163 | beverage2 = new Mocha(beverage2); 164 | beverage2 = new Whip(beverage2); 165 | System.out.println(beverage2.getDescription() 166 | + " $" + beverage2.cost()); 167 | 168 | Beverage beverage3 = new HouseBlend(); 169 | beverage3 = new Soy(beverage3); 170 | beverage3 = new Mocha(beverage3); 171 | beverage3 = new Whip(beverage3); 172 | System.out.println(beverage3.getDescription() 173 | + " $" + beverage3.cost()); 174 | } 175 | } 176 | ``` 177 | 178 | # আউটপুট 179 | 180 | ``` 181 | Espresso $1.99 182 | Dark Roast Coffee, Mocha, Mocha, Whip $1.49 183 | House Blend Coffee, Soy, Mocha, Whip $1.34 184 | ``` 185 | -------------------------------------------------------------------------------- /out/production/Design-Pattern/decorator/decorator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/decorator/decorator.png -------------------------------------------------------------------------------- /out/production/Design-Pattern/factoryMethod/CalmPizza.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/factoryMethod/CalmPizza.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/factoryMethod/CheesePizza.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/factoryMethod/CheesePizza.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/factoryMethod/Demo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/factoryMethod/Demo.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/factoryMethod/FactoryMethod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/factoryMethod/FactoryMethod.png -------------------------------------------------------------------------------- /out/production/Design-Pattern/factoryMethod/PepperoniPizza.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/factoryMethod/PepperoniPizza.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/factoryMethod/Pizza.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/factoryMethod/Pizza.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/factoryMethod/PizzaStore.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/factoryMethod/PizzaStore.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/factoryMethod/SimplePizzaFactory.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/factoryMethod/SimplePizzaFactory.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/factoryMethod/factoryMethod.md: -------------------------------------------------------------------------------- 1 | # Factory Method Pattern 2 | A Factory Pattern or Factory Method Pattern says that just define an interface or abstract class for creating an object 3 | but let the subclasses decide which class to instantiate. In other words, subclasses are responsible to create the instance of the class. 4 | 5 | # Let's we have a **pizza** store 6 | 7 | ```java 8 | public class PizzaStore{ 9 | 10 | Pizza orderPizza(){ 11 | Pizza pizza = new Pizza(); 12 | 13 | pizza.prepare(); 14 | pizza.bake(); 15 | pizza.cut(); 16 | pizza.box(); 17 | } 18 | } 19 | ``` 20 | 21 | But when we need more than one type **Pizza** ? Then we have to modify our **PizzaStore** 22 | 23 | ```java 24 | public class PizzaStore{ 25 | 26 | Pizza orderPizza(String type){ 27 | Pizza pizza; 28 | 29 | if(type.equalsIgnoreCase("cheese")){ 30 | pizza = new CheesePizza(); 31 | }else if(type.equalsIgnoreCase("pepperoni")){ 32 | pizza = new PepperoniPizza(); 33 | }else if(type.equalsIgnoreCase("calm")){ 34 | pizza = new CheesePizza(); 35 | } 36 | 37 | pizza.prepare(); 38 | pizza.bake(); 39 | pizza.cut(); 40 | pizza.box(); 41 | } 42 | } 43 | ``` 44 |

45 | Clearly, dealing with which concrete class is instantiated is really messing up 46 | our orderPizza() method and preventing it from being closed for 47 | modification. But now that we know what is varying and what isn’t, it’s 48 | probably time to encapsulate it. 49 |

50 | 51 | # Encapsulating object creation 52 |

Building a simple pizza factory

53 | 54 | ```java 55 | 56 | public class SimplePizzaFactory { 57 | public Pizza createPizza(String type){ 58 | Pizza pizza = null; 59 | 60 | if(type.equalsIgnoreCase("cheese")){ 61 | pizza = new CheesePizza(); 62 | }else if(type.equalsIgnoreCase("pepperoni")) 63 | { 64 | pizza = new PepperoniPizza(); 65 | }else if(type.equalsIgnoreCase("calm")){ 66 | pizza = new CheesePizza(); 67 | } 68 | 69 | return pizza; 70 | } 71 | } 72 | 73 | ``` 74 | 75 |

Now, our new PizzaStore will be

76 | 77 | ```java 78 | 79 | public class PizzaStore { 80 | SimplePizzaFactory factory; 81 | 82 | public PizzaStore(SimplePizzaFactory factory){ 83 | this.factory = factory; 84 | } 85 | 86 | public Pizza orderPizza(String type) 87 | { 88 | Pizza pizza; 89 | pizza = factory.createPizza(type); 90 | 91 | pizza.prepare(); 92 | pizza.bake(); 93 | pizza.cut(); 94 | pizza.box(); 95 | 96 | return pizza; 97 | } 98 | } 99 | 100 | ``` 101 | 102 | # Let's create a Driver class 103 | 104 | ```java 105 | 106 | public class Demo { 107 | public static void main(String[] args) { 108 | SimplePizzaFactory factory = new SimplePizzaFactory(); 109 | PizzaStore pizzaStore = new PizzaStore(factory); 110 | pizzaStore.orderPizza("cheese"); 111 | } 112 | } 113 | 114 | ``` 115 | 116 | Here **Pizza** is an Interface **CheesePizza**, **CalmPizza** and **PepperoniPizza** implemented this **Pizza** interface. (See code for better underesting) 117 | # UML Diagram 118 | 119 | -------------------------------------------------------------------------------- /out/production/Design-Pattern/observer/CurrentConditionsDisplay.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/observer/CurrentConditionsDisplay.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/observer/DisplalyElement.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/observer/DisplalyElement.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/observer/EventSource.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/observer/EventSource.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/observer/Observer.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/observer/Observer.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/observer/ResponseHandelerOne.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/observer/ResponseHandelerOne.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/observer/ResponseHandelerTwo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/observer/ResponseHandelerTwo.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/observer/Subject.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/observer/Subject.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/observer/WeatherData.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/observer/WeatherData.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/observer/WeatherStation.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/observer/WeatherStation.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/observer/observer.md: -------------------------------------------------------------------------------- 1 | # Problem 2 | 3 |

4 | The three players in the system are the weather station (the physical device 5 | that acquires the actual weather data), the WeatherData object (that tracks the 6 | data coming from the Weather Station and updates the displays), and the 7 | display that shows users the current weather conditions. 8 |

9 | 10 | # Let's dive into coding... 11 | 12 | ```java 13 | public class WeatherData{ 14 | 15 | public void measurementChanged(){ 16 | float temp = getTemperature(); 17 | float humidity = getHumidity(); 18 | float pressure = getPressure(); 19 | 20 | currentConditionsDisplay.update(temp, humidity, pressure); 21 | statisticsDisplay.update(temp, humidity, pressure); 22 | forecastDisplay.update(temp, humidity, pressure); 23 | } 24 | 25 | // other methods here 26 | } 27 | ``` 28 | 29 |

But does our implementation following Design principles?

30 |
    31 |
  1. We are coding to concrete implementations, not interfaces.
  2. 32 |
  3. For every new display element we need to alter code.
  4. 33 |
  5. We have no way to add (or remove) display elements at run time.
  6. 34 |
  7. The display elements don’t implement a common interface.
  8. 35 |
  9. We haven’t encapsulated the part that changes.
  10. 36 |
  11. We are violating encapsulation of the WeatherData class.
  12. 37 |
38 | 39 | # Meet the Observer Pattern 40 | We will follow **Observer** design pattern to overcome those situations. 41 |

42 | But at first we have to know how newspaper or magazine subsciptions work:

43 |
    44 |
  1. A newspaper publisher goes into business and begins publishingnewspapers.
  2. 45 |
  3. You subscribe to a particular publisher, and every time there’s a new 46 | edition it gets delivered to you. As long as you remain a subscriber, you 47 | get new newspapers.
  4. 48 |
  5. You unsubscribe when you don’t want papers anymore, and they stop being delivered.
  6. 49 |
  7. While the publisher remains in business, people, hotels, airlines, and other businesses constantly subscribe and unsubscribe to the newspaper.
  8. 50 |
51 | 52 | # Implementation 53 | As Design principles says code to interface not to implementation. So we are going to create an interface called Subject 54 | 55 | Observers will observe(listen) to this subject and will be notified when something change or update 56 | ```java 57 | public interface Subject { 58 | public void registerObserver(Observer observer); 59 | public void removeObserver(Observer observer); 60 | public void notifyObservers(); 61 | } 62 | ``` 63 | The Observer observe Subject and will be notified when subject get any update 64 | ```java 65 | public interface Observer { 66 | public void update(float temp, float humidity, float pressure); 67 | } 68 | ``` 69 | Display update info 70 | ```java 71 | public interface DisplalyElement { 72 | public void display(); 73 | } 74 | ``` 75 | 76 | Now let's implement Subject 77 | 78 | ```java 79 | 80 | public class WeatherData implements Subject{ 81 | private ArrayList observers; 82 | private float temperature; 83 | private float humidity; 84 | private float pressure; 85 | 86 | public WeatherData() 87 | { 88 | observers = new ArrayList(); 89 | } 90 | 91 | @Override 92 | public void registerObserver(Observer observer) { 93 | observers.add(observer); 94 | } 95 | 96 | @Override 97 | public void removeObserver(Observer observer) { 98 | observers.remove(observer); 99 | 100 | } 101 | 102 | @Override 103 | public void notifyObservers() { 104 | for(Observer observer: observers) 105 | { 106 | observer.update(temperature, humidity, pressure); 107 | } 108 | } 109 | 110 | public void measurementChanged(){ 111 | notifyObservers(); 112 | } 113 | 114 | public void setMeaseurements(float temperature, float humidity, float pressure) 115 | { 116 | this.temperature = temperature; 117 | this.humidity = humidity; 118 | this.pressure = pressure; 119 | measurementChanged(); 120 | } 121 | } 122 | 123 | ``` 124 | 125 | Now, Let's build those display elements. Here **CurrentConditionsDisplay** implements **Observer** and **DisplayElement**. **Observer** will notified if any update 126 | received by our Subject and this info will be render by displayElement that's why **CurrentConditionsDisplay** is implementing both of them. 127 | 128 | ```java 129 | 130 | public class CurrentConditionsDisplay implements Observer, DisplalyElement{ 131 | private float temperature; 132 | private float humidity; 133 | private float pressure; 134 | private Subject weatherData; 135 | 136 | public CurrentConditionsDisplay(Subject weatherData) { 137 | this.weatherData = weatherData; 138 | weatherData.registerObserver(this); 139 | } 140 | 141 | @Override 142 | public void update(float temp, float humidity, float pressure) { 143 | this.temperature = temp; 144 | this.humidity = humidity; 145 | display(); 146 | } 147 | 148 | @Override 149 | public void display() { 150 | System.out.println("Temperature: "+temperature+" Humidity: "+humidity+ " Pressure: "+pressure); 151 | } 152 | 153 | } 154 | 155 | ``` 156 | 157 | # Now, let's create a driver class 158 | 159 | ```java 160 | 161 | public class WeatherStation { 162 | public static void main(String[] args) { 163 | WeatherData weatherData = new WeatherData(); 164 | CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); 165 | 166 | weatherData.setMeaseurements(80, 65, 30.4f); 167 | weatherData.setMeaseurements(80, 70, 29.2f); 168 | weatherData.setMeaseurements(70, 45, 40.4f); 169 | } 170 | } 171 | 172 | ``` 173 | Display will pritn or render this 174 | ``` 175 | Temperature: 80.0 Humidity: 65.0 Pressure: 0.0 176 | Temperature: 80.0 Humidity: 70.0 Pressure: 0.0 177 | Temperature: 70.0 Humidity: 45.0 Pressure: 0.0 178 | 179 | ``` 180 | 181 | -------------------------------------------------------------------------------- /out/production/Design-Pattern/question3/Chair.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/question3/Chair.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/question3/ChairCreator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/question3/ChairCreator.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/question3/CoffeeTable.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/question3/CoffeeTable.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/question3/CoffeeTableCreator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/question3/CoffeeTableCreator.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/question3/Furniture.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/question3/Furniture.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/question3/FurnitureFactory.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/question3/FurnitureFactory.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/question3/Table.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/question3/Table.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/question3/TableCreator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/question3/TableCreator.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/singleton/Demo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/singleton/Demo.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/singleton/Singleton.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/singleton/Singleton.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/singleton/singleton.md: -------------------------------------------------------------------------------- 1 | # Singleton Pattern 2 | 3 |

একটি ক্লাসের একটি মাত্র instance থাকবে এবং একটি গ্লোভাল পয়েন্ট থাকবে যেখান থেকে সবাই instance টিকে এক্সেস করতে পারবে । 4 | The Singleton Pattern ensures a class has only one instance, and provides a global 5 | point of access to it.

6 | 7 |

Singleton Pattern মূলত ২ ধরনের :

8 |
    9 |
  1. **Early Instantiation:** একদম শুরুতে ক্লাস লোডিং এর সময় অবজেক্ট creat করে ফেলা । 10 |
  2. **Lazy Instantiation:** যখন দরকার তখন তৈরি করা । 11 |
12 | 13 | # সিঙ্গেল্টন(Singleton) প্যাটার্ন কেন লাগবে ? 14 |
    15 |
  1. এমন কিছু ক্লাস আছে যাদের instance একটির বেশী হলে প্রোগ্রামর behavior অদ্ভুত হতে পারে ! যেমন ডেটাবেজ কানেকশনের কথাই বলা যাক, আমরা যদি প্রত্যেক বার ডেটাবেজ থেকে কিছু আনতে বা কিছু রাখতে 16 | নতুন নতুন কানেকশন create করি তাহলে inconsistency তৈরি হতে পারে ।
  2. 17 |
18 | 19 | # চলুন কথা কম বলে ইমপ্লিমেন্টেশনে যাই 20 | 21 | ```java 22 | 23 | public class Singleton { 24 | private static Singleton uniqueInstance; 25 | 26 | private Singleton(){} 27 | 28 | public static Singleton getInstance(){ 29 | if(uniqueInstance == null) 30 | { 31 | uniqueInstance = new Singleton(); 32 | } 33 | return uniqueInstance; 34 | } 35 | 36 | // Other methods 37 | } 38 | ``` 39 | 40 |

Constructor **private** কেন?

41 | Singleton ক্লাসের বাহির থেকে কেও যাতে অবজেক্ট create করতে না পারে । 42 | 43 |

uniqueInstance private কেন?

44 | **private** দেওয়ার কারণ হছে এই অবজেক্টিকে কেউ যাতে সরাসরি **getInstance** method ছাড়া access করতে না পারে । 45 |

uniqueInstance static কেন?

46 | 47 | Singleton Pattern যেহেতু আমাদের আগেই বলছে একটি গ্লোভাল এক্সেস 48 | পয়েন্ট দিতে হবে । তাই আমরা **public** **static** getInstance method টি তৈরি করেছি । Access modifier e **staic** দেওয়ার কারণ হচ্ছে যে কেও যাতে যেকোন 49 | স্থান থেকে এক্সেস করতে পারে । 50 | এখন যেহেতু আমরা একবারই অবজেক্ট create করতে পাড়বো এবং এই একটি অবজেক্টই পরবর্তীতে আমাদের ব্যবহার করতে হবে , তাহলে আমাদের এই অব্জেক্তিতে কোন **variable** এ save করতে হবে । 51 | এখন যেহেতু **getInstance** method **staic** type এর তাই এই method এর ভেতর **Non static** কোন ভ্যারিয়েবল ব্যবহার করা যাবে না । এইজন্য **uniqueInstance** এর 52 | **access modifier** এ **static** ব্যবহার করা হয়েছে । 53 | 54 |

কোড দেখে মনে হচ্ছে সব কিছু ঠিক ঠাক এ আছে । কিন্তু যদি **Multithreading** এর ঝামেলা আসে ! আমাদের কোড হ্যান্ডেল করতে পারবেতো ? না, **Multithreading** যাতে কোন প্রব্লেম 55 | তৈরি করতে না পারে আমরা এমন কোন ব্যবস্থা গ্রহণ করিনি । তাহলে চলুন **getInstance** method টিকে **syncronize** করে ফেলি

56 | 57 | ```java 58 | 59 | public class Singleton { 60 | private static Singleton uniqueInstance; 61 | 62 | private Singleton(){} 63 | 64 | public static synchronized Singleton getInstance(){ 65 | if(uniqueInstance == null) 66 | { 67 | uniqueInstance = new Singleton(); 68 | } 69 | return uniqueInstance; 70 | } 71 | 72 | // Other methods 73 | } 74 | 75 | ``` 76 | 77 | # ক্লাস ডায়াগ্রাম 78 | 79 | 80 | # চলুন একটি ড্রাইভার ক্লাস লিখে কোড রান করি 81 | 82 | ```java 83 | public class Demo { 84 | public static void main(String[] args) { 85 | Singleton objOne = Singleton.getInstance(); 86 | Singleton objTwo = Singleton.getInstance(); 87 | 88 | if(objOne == objTwo){ 89 | System.out.println("Thre are same object"); 90 | } 91 | } 92 | } 93 | 94 | ``` 95 | 96 | # আউটপুট 97 | 98 | ``` 99 | Thre are same object 100 | ``` 101 | 102 | 103 | -------------------------------------------------------------------------------- /out/production/Design-Pattern/singleton/singleton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/singleton/singleton.png -------------------------------------------------------------------------------- /out/production/Design-Pattern/state/GreenLight.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/state/GreenLight.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/state/RedLight.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/state/RedLight.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/state/State.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/state/State.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/state/TestTrafficSignal.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/state/TestTrafficSignal.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/state/TrafficSystem.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/state/TrafficSystem.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/state/YellowLight.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/state/YellowLight.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/state/state.md: -------------------------------------------------------------------------------- 1 | # State Pattern 2 | 3 | কোন একটি অবজেক্টের ইন্টারনাল স্টেজ বা স্টেট পরিবর্তন হলে অবজেক্টের আচরণ অর্থাৎ কাজ বদলে ফেলা । 4 | 5 | **allow the object for changing its behavior without changing its class.** 6 | 7 | # আসুন আর একটু ভালো ভাবে বুঝা যাক 8 | 9 | যেমন ট্রাফিক সিগন্যালের কথা ধরা যাক , জখন গ্রিন লাইট জ্বলে থাকে তখন সকল ড্রাইবার বুঝতে পারে এখন তাদের পথ চলতে নিষেধ নেই । যখন গ্রিন লাইট চেঞ্জ হয়ে ইয়োলো লাইট জ্বলে তখন ড্রাইবাররা সতর্ক হয় অল্প সময়ের মধ্যে রেড লাইট অন্য হয়ে যাবে অর্থাৎ সাময়িক সময়ের জন্য যান চলাচল বন্ধ রাখতে হবে অন্য রুটের গাড়ি যেতে দেওয়ার জন্য । যখন রেড লাইট জ্বলে যায় তখন আমাদের থেমে অপেক্ষা করতে হয় চলাচলের অনুমতির জন্য অর্থাৎ গ্রিন লাইট জ্বলার অপেক্ষা করতে হয় । এখানে প্রত্যেক বার ভিন্ন ভিন্ন লাইট জ্বলার সাথে সাথে কিন্তু ড্রাইবারদের আচরণ বদলে যায় অর্থাৎ আমাদের সিস্টেম ভিন্ন আচরণ করে । 10 | 11 | # State Pattern কিন্তু ফাইনাইট স্টেট মেশিনের মতোই কাজ করে !!! 12 | 13 | 14 | 15 | আমরা কিন্তু 2nd ইয়ারে **Theory of computation** course এ
ফাইনাইট স্টেট মেশিন পড়ে এসেছি। 16 | 17 | # ইমপ্লিমেন্টেশন 18 | 19 | ```java 20 | public interface State { 21 | public void onGreenLight(); 22 | public void onYellowLight(); 23 | public void onRedLight(); 24 | } 25 | ``` 26 | 27 | ```java 28 | public class GreenLight implements State{ 29 | TrafficSystem trafficSystem; 30 | 31 | public GreenLight(TrafficSystem trafficSystem) { 32 | this.trafficSystem = trafficSystem; 33 | } 34 | 35 | @Override 36 | public void onGreenLight() { 37 | System.out.println("Moving..."); 38 | } 39 | 40 | @Override 41 | public void onYellowLight() { 42 | System.out.println("Move carefully..."); 43 | trafficSystem.setState(trafficSystem.getYellowState()); 44 | } 45 | 46 | @Override 47 | public void onRedLight() { 48 | System.out.println("Can't go from Green to Red"); 49 | } 50 | } 51 | // other method 52 | ``` 53 | 54 | ```java 55 | public class YellowLight implements State{ 56 | TrafficSystem trafficSystem; 57 | 58 | public YellowLight(TrafficSystem trafficSystem) { 59 | this.trafficSystem = trafficSystem; 60 | } 61 | 62 | @Override 63 | public void onGreenLight() { 64 | System.out.println("Can't go to Green from yellow"); 65 | } 66 | 67 | @Override 68 | public void onYellowLight() { 69 | System.out.println("Yellow light already on"); 70 | } 71 | 72 | @Override 73 | public void onRedLight() { 74 | System.out.println("Turning on red light..."); 75 | trafficSystem.setState(trafficSystem.getRedState()); 76 | } 77 | 78 | // other method 79 | } 80 | ``` 81 | 82 | ```java 83 | public class RedLight implements State{ 84 | TrafficSystem trafficSystem; 85 | 86 | public RedLight(TrafficSystem trafficSystem) { 87 | this.trafficSystem = trafficSystem; 88 | } 89 | 90 | @Override 91 | public void onGreenLight() { 92 | System.out.println("Going back to green..."); 93 | trafficSystem.setState(trafficSystem.getGreenState()); 94 | } 95 | 96 | @Override 97 | public void onYellowLight() { 98 | System.out.println("Can't go to yellow from red"); 99 | } 100 | 101 | @Override 102 | public void onRedLight() { 103 | System.out.println("Red signal already on..."); 104 | } 105 | } 106 | ``` 107 | 108 | ```java 109 | public class TrafficSystem { 110 | State green; 111 | State yellow; 112 | State red; 113 | 114 | State state; 115 | 116 | public TrafficSystem() 117 | { 118 | green = new GreenLight(this); 119 | yellow = new YellowLight(this); 120 | red = new RedLight(this); 121 | 122 | state = green; 123 | } 124 | 125 | public void turnOnGreenLight(){ 126 | state.onGreenLight(); 127 | } 128 | 129 | public void turnOnYellowLight(){ 130 | state.onYellowLight(); 131 | } 132 | 133 | public void turnOnRedLight(){ 134 | state.onRedLight(); 135 | } 136 | 137 | void setState(State state){ 138 | this.state = state; 139 | } 140 | 141 | public State getGreenState(){ 142 | return green ; 143 | } 144 | 145 | public State getYellowState(){ 146 | return yellow; 147 | } 148 | public State getRedState(){ 149 | return red; 150 | } 151 | } 152 | ``` 153 | 154 | # চলুন এবার কোড রান করে দেখা যাক 155 | 156 | ```java 157 | public class TestTrafficSignal { 158 | public static void main(String[] args) { 159 | TrafficSystem trafficSystem = new TrafficSystem(); 160 | 161 | trafficSystem.turnOnGreenLight(); 162 | trafficSystem.turnOnRedLight(); 163 | 164 | trafficSystem.turnOnYellowLight(); 165 | trafficSystem.turnOnGreenLight(); 166 | 167 | trafficSystem.turnOnRedLight(); 168 | trafficSystem.turnOnYellowLight(); 169 | trafficSystem.turnOnGreenLight(); 170 | } 171 | } 172 | ``` 173 | 174 | # আউটপুট 175 | 176 | ``` 177 | Moving... 178 | Can't go from Green to Red 179 | Move carefully... 180 | Can't go to Green from yellow 181 | Turning on red light... 182 | Can't go to yellow from red 183 | Going back to green... 184 | ``` 185 | -------------------------------------------------------------------------------- /out/production/Design-Pattern/state/stateMachine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/state/stateMachine.png -------------------------------------------------------------------------------- /out/production/Design-Pattern/strategy/Addition.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/strategy/Addition.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/strategy/Context.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/strategy/Context.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/strategy/Demo.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/strategy/Demo.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/strategy/Multiplication.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/strategy/Multiplication.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/strategy/Strategy.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/strategy/Strategy.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/strategy/Substraction.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/strategy/Substraction.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/template/CaffeineBeverage.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/template/CaffeineBeverage.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/template/CaffeineHouse.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/template/CaffeineHouse.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/template/Coffee.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/template/Coffee.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/template/Tea.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/out/production/Design-Pattern/template/Tea.class -------------------------------------------------------------------------------- /out/production/Design-Pattern/template/template.md: -------------------------------------------------------------------------------- 1 | # Template Pattern 2 | 3 | The Template Method Pattern defines the skeleton of an algorithm in a method, 4 | deferring some steps to subclasses. Template Method lets subclasses redefine certain 5 | steps of an algorithm without changing the algorithm’s structure. -------------------------------------------------------------------------------- /src/Composition/AbstractFile.java: -------------------------------------------------------------------------------- 1 | package Composition; 2 | 3 | public interface AbstractFile { 4 | void ls(); 5 | } 6 | -------------------------------------------------------------------------------- /src/Composition/CompositeDemo.java: -------------------------------------------------------------------------------- 1 | package Composition; 2 | 3 | public class CompositeDemo { 4 | public static StringBuffer compositeBuilder = new StringBuffer(); 5 | 6 | public static void main(String[] args) { 7 | Directory music = new Directory("MUSIC"); 8 | Directory scorpions = new Directory("SCORPIONS"); 9 | Directory dio = new Directory("DIO"); 10 | File track1 = new File("Don't wary, be happy.mp3"); 11 | File track2 = new File("track2.m3u"); 12 | File track3 = new File("Wind of change.mp3"); 13 | File track4 = new File("Big city night.mp3"); 14 | File track5 = new File("Rainbow in the dark.mp3"); 15 | music.add(track1); 16 | music.add(scorpions); 17 | music.add(track2); 18 | scorpions.add(track3); 19 | scorpions.add(track4); 20 | scorpions.add(dio); 21 | dio.add(track5); 22 | music.ls(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Composition/Directory.java: -------------------------------------------------------------------------------- 1 | package Composition; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class Directory implements AbstractFile { 6 | private String name; 7 | private ArrayList includeFiles = new ArrayList(); 8 | public Directory(String name) { 9 | this.name = name; 10 | } 11 | 12 | public void add(Object object){ 13 | includeFiles.add(object); 14 | } 15 | 16 | @Override 17 | public void ls() { 18 | System.out.println(CompositeDemo.compositeBuilder+ name); 19 | CompositeDemo.compositeBuilder.append(" "); 20 | 21 | for(Object includeFile :includeFiles){ 22 | AbstractFile obj = (AbstractFile) includeFile; 23 | obj.ls(); 24 | } 25 | CompositeDemo.compositeBuilder.setLength(CompositeDemo.compositeBuilder.length()-3); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Composition/File.java: -------------------------------------------------------------------------------- 1 | package Composition; 2 | 3 | public class File implements AbstractFile{ 4 | 5 | private String name; 6 | 7 | public File(String name) { 8 | this.name = name; 9 | } 10 | 11 | @Override 12 | public void ls() { 13 | System.out.println(CompositeDemo.compositeBuilder + name); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/SOLID/OpenClose/Vehicle.java: -------------------------------------------------------------------------------- 1 | package SOLID.OpenClose; 2 | 3 | public abstract class Vehicle { 4 | abstract public double calculateValue(); 5 | } 6 | class Car extends Vehicle { 7 | private final int value = 1; 8 | public int getValue() { 9 | return value; 10 | } 11 | 12 | @Override 13 | public double calculateValue() { 14 | return this.getValue() * 0.8; 15 | } 16 | } 17 | 18 | class Truck extends Vehicle { 19 | private int value = 2; 20 | public int getValue() { 21 | return value; 22 | } 23 | 24 | public double calculateValue() { 25 | return this.getValue() * 0.9; 26 | } 27 | } -------------------------------------------------------------------------------- /src/command/Command.java: -------------------------------------------------------------------------------- 1 | package command; 2 | 3 | public interface Command { 4 | public void execute(); 5 | } 6 | -------------------------------------------------------------------------------- /src/command/Light.java: -------------------------------------------------------------------------------- 1 | package command; 2 | 3 | public class Light { 4 | 5 | public Light(String name){ 6 | 7 | } 8 | 9 | public void on(){ 10 | System.out.println("Light on"); 11 | } 12 | 13 | public void off(){ 14 | System.out.println("Light off"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/command/LightOffCommand.java: -------------------------------------------------------------------------------- 1 | package command; 2 | 3 | public class LightOffCommand implements Command{ 4 | 5 | Light light; 6 | 7 | public LightOffCommand(Light light){ 8 | this.light = light; 9 | } 10 | 11 | @Override 12 | public void execute() { 13 | light.off(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/command/LightOnCommand.java: -------------------------------------------------------------------------------- 1 | package command; 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/command/NoCommand.java: -------------------------------------------------------------------------------- 1 | package command; 2 | 3 | public class NoCommand implements Command{ 4 | @Override 5 | public void execute() { 6 | 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/command/RemoteControl.java: -------------------------------------------------------------------------------- 1 | package command; 2 | 3 | public class RemoteControl { 4 | Command[] onCommands; 5 | Command[] offCommands; 6 | 7 | public RemoteControl() { 8 | onCommands = new Command[7]; 9 | offCommands = new Command[7]; 10 | 11 | Command noCommand = new NoCommand(); 12 | 13 | for(int i=0; i<7; i++) 14 | { 15 | onCommands[i] = noCommand; 16 | offCommands[i] = noCommand; 17 | } 18 | }; 19 | 20 | public void setCommand(int slot, Command onCommand, Command offCommand){ 21 | onCommands[slot] = onCommand; 22 | offCommands[slot] = offCommand; 23 | } 24 | 25 | public void onButtonWasPressed(int slot){ 26 | onCommands[slot].execute(); 27 | } 28 | 29 | public void offButtonWasPressed(int slot){ 30 | offCommands[slot].execute(); 31 | } 32 | 33 | public String toString(){ 34 | StringBuffer stringBuffer = new StringBuffer(); 35 | stringBuffer.append("----------Remote Control----------\n"); 36 | for(int i=0; i<7; i++) 37 | { 38 | stringBuffer.append("[slot "+i + "] "+ onCommands[i].getClass().getName() 39 | + " "+offCommands[i].getClass().getName()+ "\n"); 40 | } 41 | 42 | return stringBuffer.toString(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/command/RemoteLoader.java: -------------------------------------------------------------------------------- 1 | package command; 2 | 3 | public class RemoteLoader { 4 | public static void main(String[] args) { 5 | RemoteControl remote = new RemoteControl(); 6 | Light light = new Light("Living Room"); 7 | 8 | LightOnCommand lightOn = new LightOnCommand(light); 9 | LightOffCommand lightOff = new LightOffCommand(light); 10 | 11 | remote.setCommand(0, lightOn, lightOff); 12 | 13 | System.out.println(remote); 14 | 15 | remote.onButtonWasPressed(0); 16 | remote.offButtonWasPressed(0); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/command/command.md: -------------------------------------------------------------------------------- 1 | # Command Pattern 2 | 3 |

A request is wrapped under an object as command and passed to invoker object. 4 | Invoker object looks for the appropriate object which can handle this command and passes the command to the corresponding object which executes the command. 5 |

6 | -------------------------------------------------------------------------------- /src/decorator/Beverage.java: -------------------------------------------------------------------------------- 1 | package decorator; 2 | 3 | public abstract class Beverage { 4 | String description = "Unknown Beverage"; 5 | 6 | public String getDescription(){ 7 | return description; 8 | } 9 | 10 | public abstract double cost(); 11 | } 12 | -------------------------------------------------------------------------------- /src/decorator/CondimentDecorator.java: -------------------------------------------------------------------------------- 1 | package decorator; 2 | 3 | public abstract class CondimentDecorator extends Beverage{ 4 | Beverage beverage; 5 | public abstract String getDescription(); 6 | } 7 | -------------------------------------------------------------------------------- /src/decorator/DarkRoast.java: -------------------------------------------------------------------------------- 1 | package decorator; 2 | 3 | public class DarkRoast extends Beverage { 4 | public DarkRoast() { 5 | description = "Dark Roast Coffee"; 6 | } 7 | 8 | public double cost() { 9 | return .99; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/decorator/Espresso.java: -------------------------------------------------------------------------------- 1 | package decorator; 2 | 3 | public class Espresso extends Beverage{ 4 | 5 | public Espresso() { 6 | description = "Espresso"; 7 | } 8 | 9 | @Override 10 | public double cost() { 11 | return 1.99; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/decorator/HouseBlend.java: -------------------------------------------------------------------------------- 1 | package decorator; 2 | 3 | public class HouseBlend extends Beverage{ 4 | public HouseBlend() { 5 | description = "House Blend Coffee"; 6 | } 7 | 8 | @Override 9 | public double cost() { 10 | return 0.89; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/decorator/Milk.java: -------------------------------------------------------------------------------- 1 | package decorator; 2 | 3 | public class Milk extends CondimentDecorator { 4 | public Milk(Beverage beverage) { 5 | this.beverage = beverage; 6 | } 7 | 8 | public String getDescription() { 9 | return beverage.getDescription() + ", Milk"; 10 | } 11 | 12 | public double cost() { 13 | return .10 + beverage.cost(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/decorator/Mocha.java: -------------------------------------------------------------------------------- 1 | package decorator; 2 | 3 | public class Mocha extends CondimentDecorator { 4 | public Mocha(Beverage beverage) { 5 | this.beverage = beverage; 6 | } 7 | 8 | public String getDescription() { 9 | return beverage.getDescription() + ", Mocha"; 10 | } 11 | 12 | public double cost() { 13 | return .20 + beverage.cost(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/decorator/Soy.java: -------------------------------------------------------------------------------- 1 | package decorator; 2 | 3 | public class Soy extends CondimentDecorator { 4 | public Soy(Beverage beverage) { 5 | this.beverage = beverage; 6 | } 7 | 8 | public String getDescription() { 9 | return beverage.getDescription() + ", Soy"; 10 | } 11 | 12 | public double cost() { 13 | return .15 + beverage.cost(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/decorator/StarbuzzCoffee.java: -------------------------------------------------------------------------------- 1 | package decorator; 2 | 3 | public class StarbuzzCoffee { 4 | 5 | public static void main(String args[]) { 6 | Beverage beverage = new Espresso(); 7 | System.out.println(beverage.getDescription() 8 | + " $" + beverage.cost()); 9 | 10 | Beverage beverage2 = new DarkRoast(); 11 | beverage2 = new Mocha(beverage2); 12 | beverage2 = new Mocha(beverage2); 13 | beverage2 = new Whip(beverage2); 14 | System.out.println(beverage2.getDescription() 15 | + " $" + beverage2.cost()); 16 | 17 | Beverage beverage3 = new HouseBlend(); 18 | beverage3 = new Soy(beverage3); 19 | beverage3 = new Mocha(beverage3); 20 | beverage3 = new Whip(beverage3); 21 | System.out.println(beverage3.getDescription() 22 | + " $" + beverage3.cost()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/decorator/Whip.java: -------------------------------------------------------------------------------- 1 | package decorator; 2 | 3 | public class Whip extends CondimentDecorator { 4 | public Whip(Beverage beverage) { 5 | this.beverage = beverage; 6 | } 7 | 8 | public String getDescription() { 9 | return beverage.getDescription() + ", Whip"; 10 | } 11 | 12 | public double cost() { 13 | return .10 + beverage.cost(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/decorator/decorator.md: -------------------------------------------------------------------------------- 1 | # Decorator Pattern 2 | 3 | **Decorator Pattern** একজন ইউজারকে একটি অবজেক্টের স্টাকচার পরিবর্তন না করেই নতুন নতুন **functionality** যোগ করার পারমিশন দেয় । 4 | Decorator pattern allows a user to add new functionality to an existing object without altering its structure. 5 | 6 | # একটু ঝামেলা মনে হচ্ছে ? 7 | 8 | চলুন একটা উদাহরণ দিয়ে ব্যপারটা পরিষ্কার করা যাক, আমরা পেয়াজের কথাই ধরতে পারি । মুল পেয়াজের (যেটি আমরা তরকারিতে ব্যবহার করি) উপর স্তরে স্তরে যে খোসা থাকে এই প্রত্যেকটি স্তরকে 9 | আমরা এক একটি নতুন নতুন **ফিচার** ভাবতে পারি । এই খোসার স্তর কিন্তু পেয়াজের স্টাকচারকে পরিবর্তন করেনি। 10 | 11 | # চলুন আমরা একটা কফি সপ দিয়ে ফেলি 12 | 13 |

কিন্তু কফির দাম কিভাবে নির্ধারণ করবো ?

14 | এইটাতো একদন সোজা প্রত্যেক কফির একটা দাম ফিক্সড করে দিলেইতো হছে !!! 15 |

কিন্তু আমাদের কফি সপে ইচ্ছে মতো ফ্লেবার এড করা যায় । এখন প্রত্যেক নতুন নতুন ফ্লেবারের জন্য তো কিন্তু প্রাইস এড করতে হবে ! একন কি করবো ?

16 | 17 | এখনো বেশী ঝামেলার কিছুতো মনে হচ্ছে না! প্রত্যেকবার এক একটা নতুন ফ্লেবারের জন্য মুল কফির সাথে ফ্লেবারের কষ্ট যোগ করে দিলেই ঝামেলা শেষ !!! 18 | 19 | # চলুন একটু ভিজুয়ালাইজ করে ফেলি 20 | 21 | 22 | এখানে আমাদের মুল কফি হচ্ছে **DarkRoast** এটার উপর দুটো ফ্লেবার যোগ করা হয়েছে । প্রথমে **DarkRoast** এর উপর **Mocha** যোগ করা হয়েছে এবং তারপর **Whip** যোগ করা হয়েছে। এবং কফির দাম নির্ধারণের ক্ষেত্রে প্রথমে **DarkRoast** এর সাথে **Mocha** এর দাম যোগ করা হয়েছে, যোগ করার পর যে দাম পাওয়া গেছে তার সাথে **Whip** এর দম যোগ করা হয়েছে । 23 | 24 |

আশা করি আপনাদের ধারনা ক্লিয়ার হয়েছে

25 | 26 | # চলুন এবার ইমপ্লিমেন্টেশনে যাওয়া যাক 27 | 28 | এখন আমাদের কফি সপেতো আমরা জাস্ট একধরনের কফি বিক্রি করবোনা, অনেক ধরনের কফি থাকতে পারে । এবং তাদের দাম ও এক এক কফির এক এক রকম হবে । তাহলে আমরা **Beverage** নামের একটি **Abstract** ক্লাস তৈরি করে ফেলি । এখন আপনার মনে প্রশ্ন জাগতেই পারে **Abstract** ক্লাস কেন ? এর উত্তর হচ্ছে এক এক কফির দাম এক এক ভাবে ক্যালকুলেশন করা হবে, প্রত্যেকের দামতো আর এক হবেনা আর এক ভাবেও ক্যালকুলেশন করা হবেনা । এইজন্য আমরা **cost** মেথডটিকে **abstract** করলাম এখন প্রত্যেক ধরনের কফি এটাকে ইমপ্লিমেন্ট করে নিজেদের মতো দাম ক্যালকুলেশন করবে । 29 | 30 | ```java 31 | 32 | public abstract class Beverage { 33 | String description = "Unknown Beverage"; 34 | 35 | public String getDescription(){ 36 | return description; 37 | } 38 | 39 | public abstract double cost(); 40 | } 41 | 42 | ``` 43 | 44 | # প্রথমে আমরা জাস্ট **DarkRoast**, **Espresso** এবং **HouseBlend** কফি বিক্রি করবো 45 | 46 | ```java 47 | 48 | public class DarkRoast extends Beverage { 49 | public DarkRoast() { 50 | description = "Dark Roast Coffee"; 51 | } 52 | 53 | public double cost() { 54 | return .99; 55 | } 56 | } 57 | 58 | ``` 59 | 60 | ```java 61 | 62 | public class HouseBlend extends Beverage{ 63 | public HouseBlend() { 64 | description = "House Blend Coffee"; 65 | } 66 | 67 | @Override 68 | public double cost() { 69 | return 0.89; 70 | } 71 | } 72 | 73 | ``` 74 | 75 | ```java 76 | 77 | public class Espresso extends Beverage{ 78 | 79 | public Espresso() { 80 | description = "Espresso"; 81 | } 82 | 83 | @Override 84 | public double cost() { 85 | return 1.99; 86 | } 87 | } 88 | 89 | ``` 90 | 91 | # এবার ফ্লেবারে আসা যাক 92 | 93 | ```java 94 | public abstract class CondimentDecorator extends Beverage{ 95 | Beverage beverage; 96 | public abstract String getDescription(); 97 | } 98 | ``` 99 | 100 |

আমরা কেন **Beverage** ক্লাসকে **extend** করলাম ?

101 | কারণ, আমরা **Beverage** এর স্টাকচার পরিবর্তন না করেই, তার উপর লেয়ার এড করতে চাই। আমাদের যেহেতু অনেক ধরনের ফ্লেবার থাকবে পারে তাই আমরা এখনেও **getDescription** কে **abstract** রাখলাম এবং **Beverage** কে extend করে যে abstract **cost** মেথড পেলাম তাকেও ইমপ্লিমেন্ট করলাম না, এক এক ধরনের ফ্লেবার **CondimentDecorator** ক্লাসকে extend করে এগুলো নিজেকের মতো ইমপ্লিমেন্ট করে নিবে। 102 | 103 | ```java 104 | public class Mocha extends CondimentDecorator { 105 | public Mocha(Beverage beverage) { 106 | this.beverage = beverage; 107 | } 108 | 109 | public String getDescription() { 110 | return beverage.getDescription() + ", Mocha"; 111 | } 112 | 113 | public double cost() { 114 | return .20 + beverage.cost(); 115 | } 116 | } 117 | ``` 118 | 119 | ```java 120 | public class Soy extends CondimentDecorator { 121 | public Soy(Beverage beverage) { 122 | this.beverage = beverage; 123 | } 124 | 125 | public String getDescription() { 126 | return beverage.getDescription() + ", Soy"; 127 | } 128 | 129 | public double cost() { 130 | return .15 + beverage.cost(); 131 | } 132 | } 133 | ``` 134 | 135 | ```java 136 | public class Whip extends CondimentDecorator { 137 | public Whip(Beverage beverage) { 138 | this.beverage = beverage; 139 | } 140 | 141 | public String getDescription() { 142 | return beverage.getDescription() + ", Whip"; 143 | } 144 | 145 | public double cost() { 146 | return .10 + beverage.cost(); 147 | } 148 | } 149 | ``` 150 | 151 | # ঝামেলা শেষ !!! চলুন এবার কফি বাননো যাক 152 | 153 | ```java 154 | public class StarbuzzCoffee { 155 | 156 | public static void main(String args[]) { 157 | Beverage beverage = new Espresso(); 158 | System.out.println(beverage.getDescription() 159 | + " $" + beverage.cost()); 160 | 161 | Beverage beverage2 = new DarkRoast(); 162 | beverage2 = new Mocha(beverage2); 163 | beverage2 = new Mocha(beverage2); 164 | beverage2 = new Whip(beverage2); 165 | System.out.println(beverage2.getDescription() 166 | + " $" + beverage2.cost()); 167 | 168 | Beverage beverage3 = new HouseBlend(); 169 | beverage3 = new Soy(beverage3); 170 | beverage3 = new Mocha(beverage3); 171 | beverage3 = new Whip(beverage3); 172 | System.out.println(beverage3.getDescription() 173 | + " $" + beverage3.cost()); 174 | } 175 | } 176 | ``` 177 | 178 | # আউটপুট 179 | 180 | ``` 181 | Espresso $1.99 182 | Dark Roast Coffee, Mocha, Mocha, Whip $1.49 183 | House Blend Coffee, Soy, Mocha, Whip $1.34 184 | ``` 185 | -------------------------------------------------------------------------------- /src/decorator/decorator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/src/decorator/decorator.png -------------------------------------------------------------------------------- /src/factoryMethod/CalmPizza.java: -------------------------------------------------------------------------------- 1 | package factoryMethod; 2 | 3 | public class CalmPizza implements Pizza{ 4 | @Override 5 | public void prepare() { 6 | System.out.println("Preparing CalmPizza"); 7 | } 8 | 9 | @Override 10 | public void bake() { 11 | System.out.println("baking CalmPizza"); 12 | } 13 | 14 | @Override 15 | public void cut() { 16 | System.out.println("cutting CalmPizza"); 17 | } 18 | 19 | @Override 20 | public void box() { 21 | System.out.println("boxing CalmPizza"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/factoryMethod/CheesePizza.java: -------------------------------------------------------------------------------- 1 | package factoryMethod; 2 | 3 | public class CheesePizza implements Pizza{ 4 | @Override 5 | public void prepare() { 6 | System.out.println("Preparing CheesePizza"); 7 | } 8 | 9 | @Override 10 | public void bake() { 11 | System.out.println("baking CheesePizza"); 12 | } 13 | 14 | @Override 15 | public void cut() { 16 | System.out.println("cutting CheesePizza"); 17 | } 18 | 19 | @Override 20 | public void box() { 21 | System.out.println("boxing CheesePizza"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/factoryMethod/Demo.java: -------------------------------------------------------------------------------- 1 | package factoryMethod; 2 | 3 | public class Demo { 4 | public static void main(String[] args) { 5 | SimplePizzaFactory factory = new SimplePizzaFactory(); 6 | PizzaStore pizzaStore = new PizzaStore(factory); 7 | pizzaStore.orderPizza("cheese"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/factoryMethod/FactoryMethod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/src/factoryMethod/FactoryMethod.png -------------------------------------------------------------------------------- /src/factoryMethod/PepperoniPizza.java: -------------------------------------------------------------------------------- 1 | package factoryMethod; 2 | 3 | public class PepperoniPizza implements Pizza{ 4 | @Override 5 | public void prepare() { 6 | System.out.println("Preparing PepperoniPizza"); 7 | } 8 | 9 | @Override 10 | public void bake() { 11 | System.out.println("Preparing PepperoniPizza"); 12 | } 13 | 14 | @Override 15 | public void cut() { 16 | System.out.println("Preparing PepperoniPizza"); 17 | } 18 | 19 | @Override 20 | public void box() { 21 | System.out.println("Preparing PepperoniPizza"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/factoryMethod/Pizza.java: -------------------------------------------------------------------------------- 1 | package factoryMethod; 2 | 3 | public interface Pizza { 4 | public void prepare(); 5 | public void bake(); 6 | public void cut(); 7 | public void box(); 8 | } 9 | -------------------------------------------------------------------------------- /src/factoryMethod/PizzaStore.java: -------------------------------------------------------------------------------- 1 | package factoryMethod; 2 | 3 | public class PizzaStore { 4 | SimplePizzaFactory factory; 5 | 6 | public PizzaStore(SimplePizzaFactory factory){ 7 | this.factory = factory; 8 | } 9 | 10 | public Pizza orderPizza(String type) 11 | { 12 | Pizza pizza; 13 | pizza = factory.createPizza(type); 14 | 15 | pizza.prepare(); 16 | pizza.bake(); 17 | pizza.cut(); 18 | pizza.box(); 19 | 20 | return pizza; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/factoryMethod/SimplePizzaFactory.java: -------------------------------------------------------------------------------- 1 | package factoryMethod; 2 | 3 | public class SimplePizzaFactory { 4 | public Pizza createPizza(String type){ 5 | Pizza pizza = null; 6 | 7 | if(type.equalsIgnoreCase("cheese")){ 8 | pizza = new CheesePizza(); 9 | }else if(type.equalsIgnoreCase("pepperoni")) 10 | { 11 | pizza = new PepperoniPizza(); 12 | }else if(type.equalsIgnoreCase("calm")){ 13 | pizza = new CheesePizza(); 14 | } 15 | 16 | return pizza; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/factoryMethod/factoryMethod.md: -------------------------------------------------------------------------------- 1 | # Factory Method Pattern 2 | A Factory Pattern or Factory Method Pattern says that just define an interface or abstract class for creating an object 3 | but let the subclasses decide which class to instantiate. In other words, subclasses are responsible to create the instance of the class. 4 | 5 | # Let's we have a **pizza** store 6 | 7 | ```java 8 | public class PizzaStore{ 9 | 10 | Pizza orderPizza(){ 11 | Pizza pizza = new Pizza(); 12 | 13 | pizza.prepare(); 14 | pizza.bake(); 15 | pizza.cut(); 16 | pizza.box(); 17 | } 18 | } 19 | ``` 20 | 21 | But when we need more than one type **Pizza** ? Then we have to modify our **PizzaStore** 22 | 23 | ```java 24 | public class PizzaStore{ 25 | 26 | Pizza orderPizza(String type){ 27 | Pizza pizza; 28 | 29 | if(type.equalsIgnoreCase("cheese")){ 30 | pizza = new CheesePizza(); 31 | }else if(type.equalsIgnoreCase("pepperoni")){ 32 | pizza = new PepperoniPizza(); 33 | }else if(type.equalsIgnoreCase("calm")){ 34 | pizza = new CheesePizza(); 35 | } 36 | 37 | pizza.prepare(); 38 | pizza.bake(); 39 | pizza.cut(); 40 | pizza.box(); 41 | } 42 | } 43 | ``` 44 |

45 | Clearly, dealing with which concrete class is instantiated is really messing up 46 | our orderPizza() method and preventing it from being closed for 47 | modification. But now that we know what is varying and what isn’t, it’s 48 | probably time to encapsulate it. 49 |

50 | 51 | # Encapsulating object creation 52 |

Building a simple pizza factory

53 | 54 | ```java 55 | 56 | public class SimplePizzaFactory { 57 | public Pizza createPizza(String type){ 58 | Pizza pizza = null; 59 | 60 | if(type.equalsIgnoreCase("cheese")){ 61 | pizza = new CheesePizza(); 62 | }else if(type.equalsIgnoreCase("pepperoni")) 63 | { 64 | pizza = new PepperoniPizza(); 65 | }else if(type.equalsIgnoreCase("calm")){ 66 | pizza = new CheesePizza(); 67 | } 68 | 69 | return pizza; 70 | } 71 | } 72 | 73 | ``` 74 | 75 |

Now, our new PizzaStore will be

76 | 77 | ```java 78 | 79 | public class PizzaStore { 80 | SimplePizzaFactory factory; 81 | 82 | public PizzaStore(SimplePizzaFactory factory){ 83 | this.factory = factory; 84 | } 85 | 86 | public Pizza orderPizza(String type) 87 | { 88 | Pizza pizza; 89 | pizza = factory.createPizza(type); 90 | 91 | pizza.prepare(); 92 | pizza.bake(); 93 | pizza.cut(); 94 | pizza.box(); 95 | 96 | return pizza; 97 | } 98 | } 99 | 100 | ``` 101 | 102 | # Let's create a Driver class 103 | 104 | ```java 105 | 106 | public class Demo { 107 | public static void main(String[] args) { 108 | SimplePizzaFactory factory = new SimplePizzaFactory(); 109 | PizzaStore pizzaStore = new PizzaStore(factory); 110 | pizzaStore.orderPizza("cheese"); 111 | } 112 | } 113 | 114 | ``` 115 | 116 | Here **Pizza** is an Interface **CheesePizza**, **CalmPizza** and **PepperoniPizza** implemented this **Pizza** interface. (See code for better underesting) 117 | # UML Diagram 118 | 119 | -------------------------------------------------------------------------------- /src/observer/CurrentConditionsDisplay.java: -------------------------------------------------------------------------------- 1 | package observer; 2 | 3 | public class CurrentConditionsDisplay implements Observer, DisplalyElement{ 4 | private float temperature; 5 | private float humidity; 6 | private float pressure; 7 | private Subject weatherData; 8 | 9 | public CurrentConditionsDisplay(Subject weatherData) { 10 | this.weatherData = weatherData; 11 | weatherData.registerObserver(this); 12 | } 13 | 14 | @Override 15 | public void update(float temp, float humidity, float pressure) { 16 | this.temperature = temp; 17 | this.humidity = humidity; 18 | display(); 19 | } 20 | 21 | @Override 22 | public void display() { 23 | System.out.println("Temperature: "+temperature+" Humidity: "+humidity+ " Pressure: "+pressure); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/observer/DisplalyElement.java: -------------------------------------------------------------------------------- 1 | package observer; 2 | 3 | public interface DisplalyElement { 4 | public void display(); 5 | } 6 | -------------------------------------------------------------------------------- /src/observer/EventSource.java: -------------------------------------------------------------------------------- 1 | package observer; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.util.Observable; 7 | 8 | public class EventSource extends Observable implements Runnable { 9 | @Override 10 | public void run() { 11 | try { 12 | final InputStreamReader inputStreamReader = new InputStreamReader(System.in); 13 | final BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 14 | 15 | while (true) 16 | { 17 | String response = bufferedReader.readLine(); 18 | setChanged(); 19 | notifyObservers(response); 20 | } 21 | } catch (IOException e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | 26 | public static void main(String[] args) { 27 | EventSource eventSource = new EventSource(); 28 | eventSource.run(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/observer/Observer.java: -------------------------------------------------------------------------------- 1 | package observer; 2 | 3 | public interface Observer { 4 | public void update(float temp, float humidity, float pressure); 5 | } 6 | -------------------------------------------------------------------------------- /src/observer/ResponseHandelerOne.java: -------------------------------------------------------------------------------- 1 | package observer; 2 | 3 | import java.util.Observable; 4 | import java.util.Observer; 5 | 6 | public class ResponseHandelerOne implements Observer { 7 | private String resp; 8 | @Override 9 | public void update(Observable o, Object arg) { 10 | if(arg instanceof String){ 11 | resp = (String) arg; 12 | System.out.println("Received response: "+resp); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/observer/ResponseHandelerTwo.java: -------------------------------------------------------------------------------- 1 | package observer; 2 | 3 | import java.util.Observable; 4 | import java.util.Observer; 5 | 6 | public class ResponseHandelerTwo implements Observer { 7 | private String resp; 8 | @Override 9 | public void update(Observable o, Object arg) { 10 | if(arg instanceof String) 11 | { 12 | resp = (String) arg; 13 | System.out.println("Response received: "+resp); 14 | } 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/observer/Subject.java: -------------------------------------------------------------------------------- 1 | package observer; 2 | 3 | public interface Subject { 4 | public void registerObserver(Observer observer); 5 | public void removeObserver(Observer observer); 6 | public void notifyObservers(); 7 | } 8 | -------------------------------------------------------------------------------- /src/observer/WeatherData.java: -------------------------------------------------------------------------------- 1 | package observer; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class WeatherData implements Subject{ 6 | private ArrayList observers; 7 | private float temperature; 8 | private float humidity; 9 | private float pressure; 10 | 11 | public WeatherData() 12 | { 13 | observers = new ArrayList(); 14 | } 15 | 16 | @Override 17 | public void registerObserver(Observer observer) { 18 | observers.add(observer); 19 | } 20 | 21 | @Override 22 | public void removeObserver(Observer observer) { 23 | observers.remove(observer); 24 | 25 | } 26 | 27 | @Override 28 | public void notifyObservers() { 29 | for(Observer observer: observers) 30 | { 31 | observer.update(temperature, humidity, pressure); 32 | } 33 | } 34 | 35 | public void measurementChanged(){ 36 | notifyObservers(); 37 | } 38 | 39 | public void setMeaseurements(float temperature, float humidity, float pressure) 40 | { 41 | this.temperature = temperature; 42 | this.humidity = humidity; 43 | this.pressure = pressure; 44 | measurementChanged(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/observer/WeatherStation.java: -------------------------------------------------------------------------------- 1 | package observer; 2 | 3 | public class WeatherStation { 4 | public static void main(String[] args) { 5 | WeatherData weatherData = new WeatherData(); 6 | CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); 7 | 8 | weatherData.setMeaseurements(80, 65, 30.4f); 9 | weatherData.setMeaseurements(80, 70, 29.2f); 10 | weatherData.setMeaseurements(70, 45, 40.4f); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/observer/observer.md: -------------------------------------------------------------------------------- 1 | # Problem 2 | 3 |

4 | The three players in the system are the weather station (the physical device 5 | that acquires the actual weather data), the WeatherData object (that tracks the 6 | data coming from the Weather Station and updates the displays), and the 7 | display that shows users the current weather conditions. 8 |

9 | 10 | # Let's dive into coding... 11 | 12 | ```java 13 | public class WeatherData{ 14 | 15 | public void measurementChanged(){ 16 | float temp = getTemperature(); 17 | float humidity = getHumidity(); 18 | float pressure = getPressure(); 19 | 20 | currentConditionsDisplay.update(temp, humidity, pressure); 21 | statisticsDisplay.update(temp, humidity, pressure); 22 | forecastDisplay.update(temp, humidity, pressure); 23 | } 24 | 25 | // other methods here 26 | } 27 | ``` 28 | 29 |

But does our implementation following Design principles?

30 |
    31 |
  1. We are coding to concrete implementations, not interfaces.
  2. 32 |
  3. For every new display element we need to alter code.
  4. 33 |
  5. We have no way to add (or remove) display elements at run time.
  6. 34 |
  7. The display elements don’t implement a common interface.
  8. 35 |
  9. We haven’t encapsulated the part that changes.
  10. 36 |
  11. We are violating encapsulation of the WeatherData class.
  12. 37 |
38 | 39 | # Meet the Observer Pattern 40 | We will follow **Observer** design pattern to overcome those situations. 41 |

42 | But at first we have to know how newspaper or magazine subsciptions work:

43 |
    44 |
  1. A newspaper publisher goes into business and begins publishingnewspapers.
  2. 45 |
  3. You subscribe to a particular publisher, and every time there’s a new 46 | edition it gets delivered to you. As long as you remain a subscriber, you 47 | get new newspapers.
  4. 48 |
  5. You unsubscribe when you don’t want papers anymore, and they stop being delivered.
  6. 49 |
  7. While the publisher remains in business, people, hotels, airlines, and other businesses constantly subscribe and unsubscribe to the newspaper.
  8. 50 |
51 | 52 | # Implementation 53 | As Design principles says code to interface not to implementation. So we are going to create an interface called Subject 54 | 55 | Observers will observe(listen) to this subject and will be notified when something change or update 56 | ```java 57 | public interface Subject { 58 | public void registerObserver(Observer observer); 59 | public void removeObserver(Observer observer); 60 | public void notifyObservers(); 61 | } 62 | ``` 63 | The Observer observe Subject and will be notified when subject get any update 64 | ```java 65 | public interface Observer { 66 | public void update(float temp, float humidity, float pressure); 67 | } 68 | ``` 69 | Display update info 70 | ```java 71 | public interface DisplalyElement { 72 | public void display(); 73 | } 74 | ``` 75 | 76 | Now let's implement Subject 77 | 78 | ```java 79 | 80 | public class WeatherData implements Subject{ 81 | private ArrayList observers; 82 | private float temperature; 83 | private float humidity; 84 | private float pressure; 85 | 86 | public WeatherData() 87 | { 88 | observers = new ArrayList(); 89 | } 90 | 91 | @Override 92 | public void registerObserver(Observer observer) { 93 | observers.add(observer); 94 | } 95 | 96 | @Override 97 | public void removeObserver(Observer observer) { 98 | observers.remove(observer); 99 | 100 | } 101 | 102 | @Override 103 | public void notifyObservers() { 104 | for(Observer observer: observers) 105 | { 106 | observer.update(temperature, humidity, pressure); 107 | } 108 | } 109 | 110 | public void measurementChanged(){ 111 | notifyObservers(); 112 | } 113 | 114 | public void setMeaseurements(float temperature, float humidity, float pressure) 115 | { 116 | this.temperature = temperature; 117 | this.humidity = humidity; 118 | this.pressure = pressure; 119 | measurementChanged(); 120 | } 121 | } 122 | 123 | ``` 124 | 125 | Now, Let's build those display elements. Here **CurrentConditionsDisplay** implements **Observer** and **DisplayElement**. **Observer** will notified if any update 126 | received by our Subject and this info will be render by displayElement that's why **CurrentConditionsDisplay** is implementing both of them. 127 | 128 | ```java 129 | 130 | public class CurrentConditionsDisplay implements Observer, DisplalyElement{ 131 | private float temperature; 132 | private float humidity; 133 | private float pressure; 134 | private Subject weatherData; 135 | 136 | public CurrentConditionsDisplay(Subject weatherData) { 137 | this.weatherData = weatherData; 138 | weatherData.registerObserver(this); 139 | } 140 | 141 | @Override 142 | public void update(float temp, float humidity, float pressure) { 143 | this.temperature = temp; 144 | this.humidity = humidity; 145 | display(); 146 | } 147 | 148 | @Override 149 | public void display() { 150 | System.out.println("Temperature: "+temperature+" Humidity: "+humidity+ " Pressure: "+pressure); 151 | } 152 | 153 | } 154 | 155 | ``` 156 | 157 | # Now, let's create a driver class 158 | 159 | ```java 160 | 161 | public class WeatherStation { 162 | public static void main(String[] args) { 163 | WeatherData weatherData = new WeatherData(); 164 | CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); 165 | 166 | weatherData.setMeaseurements(80, 65, 30.4f); 167 | weatherData.setMeaseurements(80, 70, 29.2f); 168 | weatherData.setMeaseurements(70, 45, 40.4f); 169 | } 170 | } 171 | 172 | ``` 173 | Display will pritn or render this 174 | ``` 175 | Temperature: 80.0 Humidity: 65.0 Pressure: 0.0 176 | Temperature: 80.0 Humidity: 70.0 Pressure: 0.0 177 | Temperature: 70.0 Humidity: 45.0 Pressure: 0.0 178 | 179 | ``` 180 | 181 | -------------------------------------------------------------------------------- /src/question3/Furniture.java: -------------------------------------------------------------------------------- 1 | package question3; 2 | 3 | public class Furniture{ 4 | // Do something 5 | } 6 | 7 | class Table extends Furniture{ 8 | // Do something 9 | } 10 | 11 | class Chair extends Furniture{ 12 | // Do something 13 | } 14 | 15 | class CoffeeTable extends Furniture{ 16 | // Do something 17 | } 18 | 19 | 20 | interface FurnitureFactory{ 21 | 22 | public Furniture createFurniture(); 23 | } 24 | 25 | class TableCreator implements FurnitureFactory{ 26 | 27 | @Override 28 | public Furniture createFurniture() { 29 | return new Table(); 30 | } 31 | } 32 | 33 | class ChairCreator implements FurnitureFactory{ 34 | 35 | @Override 36 | public Furniture createFurniture() { 37 | return new Chair(); 38 | } 39 | } 40 | 41 | class CoffeeTableCreator implements FurnitureFactory{ 42 | 43 | @Override 44 | public Furniture createFurniture() { 45 | return new CoffeeTable(); 46 | } 47 | } -------------------------------------------------------------------------------- /src/singleton/Demo.java: -------------------------------------------------------------------------------- 1 | package singleton; 2 | 3 | public class Demo { 4 | public static void main(String[] args) { 5 | Singleton objOne = Singleton.getInstance(); 6 | Singleton objTwo = Singleton.getInstance(); 7 | 8 | if(objOne == objTwo){ 9 | System.out.println("Thre are same object"); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/singleton/Singleton.java: -------------------------------------------------------------------------------- 1 | package singleton; 2 | 3 | public class Singleton { 4 | private static Singleton uniqueInstance; 5 | 6 | private Singleton(){} 7 | 8 | public static synchronized Singleton getInstance(){ 9 | if(uniqueInstance == null) 10 | { 11 | uniqueInstance = new Singleton(); 12 | } 13 | return uniqueInstance; 14 | } 15 | 16 | // Other methods 17 | } 18 | -------------------------------------------------------------------------------- /src/singleton/singleton.md: -------------------------------------------------------------------------------- 1 | # Singleton Pattern 2 | 3 |

একটি ক্লাসের একটি মাত্র instance থাকবে এবং একটি গ্লোভাল পয়েন্ট থাকবে যেখান থেকে সবাই instance টিকে এক্সেস করতে পারবে । 4 | The Singleton Pattern ensures a class has only one instance, and provides a global 5 | point of access to it.

6 | 7 |

Singleton Pattern মূলত ২ ধরনের :

8 |
    9 |
  1. **Early Instantiation:** একদম শুরুতে ক্লাস লোডিং এর সময় অবজেক্ট creat করে ফেলা । 10 |
  2. **Lazy Instantiation:** যখন দরকার তখন তৈরি করা । 11 |
12 | 13 | # সিঙ্গেল্টন(Singleton) প্যাটার্ন কেন লাগবে ? 14 |
    15 |
  1. এমন কিছু ক্লাস আছে যাদের instance একটির বেশী হলে প্রোগ্রামর behavior অদ্ভুত হতে পারে ! যেমন ডেটাবেজ কানেকশনের কথাই বলা যাক, আমরা যদি প্রত্যেক বার ডেটাবেজ থেকে কিছু আনতে বা কিছু রাখতে 16 | নতুন নতুন কানেকশন create করি তাহলে inconsistency তৈরি হতে পারে ।
  2. 17 |
18 | 19 | # চলুন কথা কম বলে ইমপ্লিমেন্টেশনে যাই 20 | 21 | ```java 22 | 23 | public class Singleton { 24 | private static Singleton uniqueInstance; 25 | 26 | private Singleton(){} 27 | 28 | public static Singleton getInstance(){ 29 | if(uniqueInstance == null) 30 | { 31 | uniqueInstance = new Singleton(); 32 | } 33 | return uniqueInstance; 34 | } 35 | 36 | // Other methods 37 | } 38 | ``` 39 | 40 |

Constructor **private** কেন?

41 | Singleton ক্লাসের বাহির থেকে কেও যাতে অবজেক্ট create করতে না পারে । 42 | 43 |

uniqueInstance private কেন?

44 | **private** দেওয়ার কারণ হছে এই অবজেক্টিকে কেউ যাতে সরাসরি **getInstance** method ছাড়া access করতে না পারে । 45 |

uniqueInstance static কেন?

46 | 47 | Singleton Pattern যেহেতু আমাদের আগেই বলছে একটি গ্লোভাল এক্সেস 48 | পয়েন্ট দিতে হবে । তাই আমরা **public** **static** getInstance method টি তৈরি করেছি । Access modifier e **staic** দেওয়ার কারণ হচ্ছে যে কেও যাতে যেকোন 49 | স্থান থেকে এক্সেস করতে পারে । 50 | এখন যেহেতু আমরা একবারই অবজেক্ট create করতে পাড়বো এবং এই একটি অবজেক্টই পরবর্তীতে আমাদের ব্যবহার করতে হবে , তাহলে আমাদের এই অব্জেক্তিতে কোন **variable** এ save করতে হবে । 51 | এখন যেহেতু **getInstance** method **staic** type এর তাই এই method এর ভেতর **Non static** কোন ভ্যারিয়েবল ব্যবহার করা যাবে না । এইজন্য **uniqueInstance** এর 52 | **access modifier** এ **static** ব্যবহার করা হয়েছে । 53 | 54 |

কোড দেখে মনে হচ্ছে সব কিছু ঠিক ঠাক এ আছে । কিন্তু যদি **Multithreading** এর ঝামেলা আসে ! আমাদের কোড হ্যান্ডেল করতে পারবেতো ? না, **Multithreading** যাতে কোন প্রব্লেম 55 | তৈরি করতে না পারে আমরা এমন কোন ব্যবস্থা গ্রহণ করিনি । তাহলে চলুন **getInstance** method টিকে **syncronize** করে ফেলি

56 | 57 | ```java 58 | 59 | public class Singleton { 60 | private static Singleton uniqueInstance; 61 | 62 | private Singleton(){} 63 | 64 | public static synchronized Singleton getInstance(){ 65 | if(uniqueInstance == null) 66 | { 67 | uniqueInstance = new Singleton(); 68 | } 69 | return uniqueInstance; 70 | } 71 | 72 | // Other methods 73 | } 74 | 75 | ``` 76 | 77 | # ক্লাস ডায়াগ্রাম 78 | 79 | 80 | # চলুন একটি ড্রাইভার ক্লাস লিখে কোড রান করি 81 | 82 | ```java 83 | public class Demo { 84 | public static void main(String[] args) { 85 | Singleton objOne = Singleton.getInstance(); 86 | Singleton objTwo = Singleton.getInstance(); 87 | 88 | if(objOne == objTwo){ 89 | System.out.println("Thre are same object"); 90 | } 91 | } 92 | } 93 | 94 | ``` 95 | 96 | # আউটপুট 97 | 98 | ``` 99 | Thre are same object 100 | ``` 101 | 102 | 103 | -------------------------------------------------------------------------------- /src/singleton/singleton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/src/singleton/singleton.png -------------------------------------------------------------------------------- /src/state/GreenLight.java: -------------------------------------------------------------------------------- 1 | package state; 2 | 3 | public class GreenLight implements State{ 4 | TrafficSystem trafficSystem; 5 | 6 | public GreenLight(TrafficSystem trafficSystem) { 7 | this.trafficSystem = trafficSystem; 8 | } 9 | 10 | @Override 11 | public void onGreenLight() { 12 | System.out.println("Moving..."); 13 | } 14 | 15 | @Override 16 | public void onYellowLight() { 17 | System.out.println("Move carefully..."); 18 | trafficSystem.setState(trafficSystem.getYellowState()); 19 | } 20 | 21 | @Override 22 | public void onRedLight() { 23 | System.out.println("Can't go from Green to Red"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/state/RedLight.java: -------------------------------------------------------------------------------- 1 | package state; 2 | 3 | public class RedLight implements State{ 4 | TrafficSystem trafficSystem; 5 | 6 | public RedLight(TrafficSystem trafficSystem) { 7 | this.trafficSystem = trafficSystem; 8 | } 9 | 10 | @Override 11 | public void onGreenLight() { 12 | System.out.println("Going back to green..."); 13 | trafficSystem.setState(trafficSystem.getGreenState()); 14 | } 15 | 16 | @Override 17 | public void onYellowLight() { 18 | System.out.println("Can't go to yellow from red"); 19 | } 20 | 21 | @Override 22 | public void onRedLight() { 23 | System.out.println("Red signal already on..."); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/state/State.java: -------------------------------------------------------------------------------- 1 | package state; 2 | 3 | public interface State { 4 | public void onGreenLight(); 5 | public void onYellowLight(); 6 | public void onRedLight(); 7 | } 8 | -------------------------------------------------------------------------------- /src/state/TestTrafficSignal.java: -------------------------------------------------------------------------------- 1 | package state; 2 | 3 | public class TestTrafficSignal { 4 | public static void main(String[] args) { 5 | TrafficSystem trafficSystem = new TrafficSystem(); 6 | 7 | trafficSystem.turnOnGreenLight(); 8 | trafficSystem.turnOnRedLight(); 9 | 10 | trafficSystem.turnOnYellowLight(); 11 | trafficSystem.turnOnGreenLight(); 12 | 13 | trafficSystem.turnOnRedLight(); 14 | trafficSystem.turnOnYellowLight(); 15 | trafficSystem.turnOnGreenLight(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/state/TrafficSystem.java: -------------------------------------------------------------------------------- 1 | package state; 2 | 3 | public class TrafficSystem { 4 | State green; 5 | State yellow; 6 | State red; 7 | 8 | State state; 9 | 10 | public TrafficSystem() 11 | { 12 | green = new GreenLight(this); 13 | yellow = new YellowLight(this); 14 | red = new RedLight(this); 15 | 16 | state = green; 17 | } 18 | 19 | public void turnOnGreenLight(){ 20 | state.onGreenLight(); 21 | } 22 | 23 | public void turnOnYellowLight(){ 24 | state.onYellowLight(); 25 | } 26 | 27 | public void turnOnRedLight(){ 28 | state.onRedLight(); 29 | } 30 | 31 | void setState(State state){ 32 | this.state = state; 33 | } 34 | 35 | public State getGreenState(){ 36 | return green ; 37 | } 38 | 39 | public State getYellowState(){ 40 | return yellow; 41 | } 42 | public State getRedState(){ 43 | return red; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/state/TrafficSystemWithoutPattern.java: -------------------------------------------------------------------------------- 1 | package state; 2 | 3 | public class TrafficSystemWithoutPattern { 4 | boolean green; 5 | boolean yellow; 6 | boolean red; 7 | 8 | public TrafficSystemWithoutPattern() { 9 | green = true; 10 | yellow= false; 11 | red = false; 12 | } 13 | 14 | public void driveCar(){ 15 | if(green) 16 | { 17 | System.out.println("Car is running..."); 18 | }else if(yellow){ 19 | System.out.println("move slowly."); 20 | }else if(red){ 21 | System.out.println("Wait until green light is on"); 22 | } 23 | } 24 | 25 | public void greenLightOn(){ 26 | green = true; 27 | yellow = false; 28 | red = false; 29 | } 30 | 31 | public void yellowLightOn(){ 32 | yellow = true; 33 | green = false; 34 | red = false; 35 | } 36 | 37 | public void redLightOn(){ 38 | green = false; 39 | yellow = false; 40 | red = true; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/state/YellowLight.java: -------------------------------------------------------------------------------- 1 | package state; 2 | 3 | public class YellowLight implements State{ 4 | TrafficSystem trafficSystem; 5 | 6 | public YellowLight(TrafficSystem trafficSystem) { 7 | this.trafficSystem = trafficSystem; 8 | } 9 | 10 | @Override 11 | public void onGreenLight() { 12 | System.out.println("Can't go to Green from yellow"); 13 | } 14 | 15 | @Override 16 | public void onYellowLight() { 17 | System.out.println("Yellow light already on"); 18 | } 19 | 20 | @Override 21 | public void onRedLight() { 22 | System.out.println("Turning on red light..."); 23 | trafficSystem.setState(trafficSystem.getRedState()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/state/state.md: -------------------------------------------------------------------------------- 1 | # State Pattern 2 | 3 | কোন একটি অবজেক্টের ইন্টারনাল স্টেজ বা স্টেট পরিবর্তন হলে অবজেক্টের আচরণ অর্থাৎ কাজ বদলে ফেলা । 4 | 5 | **allow the object for changing its behavior without changing its class.** 6 | 7 | # আসুন আর একটু ভালো ভাবে বুঝা যাক 8 | 9 | যেমন ট্রাফিক সিগন্যালের কথা ধরা যাক , যখন গ্রিন লাইট জ্বলে থাকে তখন সকল ড্রাইবার বুঝতে পারে এখন তাদের পথ চলতে নিষেধ নেই । যখন গ্রিন লাইট চেঞ্জ হয়ে ইয়োলো লাইট জ্বলে তখন ড্রাইবাররা সতর্ক হয়, কারণ অল্প সময়ের মধ্যে রেড লাইট অন হয়ে যাবে অর্থাৎ সাময়িক সময়ের জন্য যান চলাচল বন্ধ রাখতে হবে অন্য রুটের গাড়ি যেতে দেওয়ার জন্য । যখন রেড লাইট জ্বলে যায় তখন আমাদের থেমে অপেক্ষা করতে হয় চলাচলের অনুমতির জন্য অর্থাৎ গ্রিন লাইট জ্বলার অপেক্ষা করতে হয় । এখানে প্রত্যেক বার ভিন্ন ভিন্ন লাইট জ্বলার সাথে সাথে কিন্তু আমাদের ট্রাফিক সিগন্যাল সিস্টেমের স্টেট বদলে যায় এবং ড্রাইবারদের আচরণ ও বদলে যায় অর্থাৎ আমাদের সিস্টেম ভিন্ন আচরণ করে । এখানে **গ্রিন লাইট** , **ইয়োলো লাইট** এবং **রেড লাইট** এক একটি স্টেট 10 | 11 | # State Pattern কিন্তু ফাইনাইট স্টেট মেশিনের মতোই কাজ করে !!! 12 | 13 | 14 | 15 | আমরা কিন্তু 2nd ইয়ারে **Theory of computation** course এ ফাইনাইট স্টেট মেশিন পড়ে এসেছি। 16 | 17 | # ইমপ্লিমেন্টেশন 18 | 19 | ```java 20 | public interface State { 21 | public void onGreenLight(); 22 | public void onYellowLight(); 23 | public void onRedLight(); 24 | } 25 | ``` 26 | 27 | ```java 28 | public class GreenLight implements State{ 29 | TrafficSystem trafficSystem; 30 | 31 | public GreenLight(TrafficSystem trafficSystem) { 32 | this.trafficSystem = trafficSystem; 33 | } 34 | 35 | @Override 36 | public void onGreenLight() { 37 | System.out.println("Moving..."); 38 | } 39 | 40 | @Override 41 | public void onYellowLight() { 42 | System.out.println("Move carefully..."); 43 | trafficSystem.setState(trafficSystem.getYellowState()); 44 | } 45 | 46 | @Override 47 | public void onRedLight() { 48 | System.out.println("Can't go from Green to Red"); 49 | } 50 | } 51 | // other method 52 | ``` 53 | 54 | ```java 55 | public class YellowLight implements State{ 56 | TrafficSystem trafficSystem; 57 | 58 | public YellowLight(TrafficSystem trafficSystem) { 59 | this.trafficSystem = trafficSystem; 60 | } 61 | 62 | @Override 63 | public void onGreenLight() { 64 | System.out.println("Can't go to Green from yellow"); 65 | } 66 | 67 | @Override 68 | public void onYellowLight() { 69 | System.out.println("Yellow light already on"); 70 | } 71 | 72 | @Override 73 | public void onRedLight() { 74 | System.out.println("Turning on red light..."); 75 | trafficSystem.setState(trafficSystem.getRedState()); 76 | } 77 | 78 | // other method 79 | } 80 | ``` 81 | 82 | ```java 83 | public class RedLight implements State{ 84 | TrafficSystem trafficSystem; 85 | 86 | public RedLight(TrafficSystem trafficSystem) { 87 | this.trafficSystem = trafficSystem; 88 | } 89 | 90 | @Override 91 | public void onGreenLight() { 92 | System.out.println("Going back to green..."); 93 | trafficSystem.setState(trafficSystem.getGreenState()); 94 | } 95 | 96 | @Override 97 | public void onYellowLight() { 98 | System.out.println("Can't go to yellow from red"); 99 | } 100 | 101 | @Override 102 | public void onRedLight() { 103 | System.out.println("Red signal already on..."); 104 | } 105 | } 106 | ``` 107 | 108 | ```java 109 | public class TrafficSystem { 110 | State green; 111 | State yellow; 112 | State red; 113 | 114 | State state; 115 | 116 | public TrafficSystem() 117 | { 118 | green = new GreenLight(this); 119 | yellow = new YellowLight(this); 120 | red = new RedLight(this); 121 | 122 | state = green; 123 | } 124 | 125 | public void turnOnGreenLight(){ 126 | state.onGreenLight(); 127 | } 128 | 129 | public void turnOnYellowLight(){ 130 | state.onYellowLight(); 131 | } 132 | 133 | public void turnOnRedLight(){ 134 | state.onRedLight(); 135 | } 136 | 137 | void setState(State state){ 138 | this.state = state; 139 | } 140 | 141 | public State getGreenState(){ 142 | return green ; 143 | } 144 | 145 | public State getYellowState(){ 146 | return yellow; 147 | } 148 | public State getRedState(){ 149 | return red; 150 | } 151 | } 152 | ``` 153 | 154 | # চলুন এবার কোড রান করে দেখা যাক 155 | 156 | ```java 157 | public class TestTrafficSignal { 158 | public static void main(String[] args) { 159 | TrafficSystem trafficSystem = new TrafficSystem(); 160 | 161 | trafficSystem.turnOnGreenLight(); 162 | trafficSystem.turnOnRedLight(); 163 | 164 | trafficSystem.turnOnYellowLight(); 165 | trafficSystem.turnOnGreenLight(); 166 | 167 | trafficSystem.turnOnRedLight(); 168 | trafficSystem.turnOnYellowLight(); 169 | trafficSystem.turnOnGreenLight(); 170 | } 171 | } 172 | ``` 173 | 174 | # আউটপুট 175 | 176 | ``` 177 | Moving... 178 | Can't go from Green to Red 179 | Move carefully... 180 | Can't go to Green from yellow 181 | Turning on red light... 182 | Can't go to yellow from red 183 | Going back to green... 184 | ``` 185 | -------------------------------------------------------------------------------- /src/state/stateMachine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/src/state/stateMachine.png -------------------------------------------------------------------------------- /src/strategy/Addition.java: -------------------------------------------------------------------------------- 1 | package strategy; 2 | 3 | public class Addition implements Strategy{ 4 | @Override 5 | public float calculation(float a, float b) { 6 | return a+b; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/strategy/Context.java: -------------------------------------------------------------------------------- 1 | package strategy; 2 | 3 | public class Context { 4 | private Strategy strategy; 5 | 6 | public Context(Strategy strategy){ 7 | this.strategy = strategy; 8 | } 9 | 10 | public float executeStrategy(float num1, float num2){ 11 | return strategy.calculation(num1, num2); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/strategy/Demo.java: -------------------------------------------------------------------------------- 1 | package strategy; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | 7 | public class Demo { 8 | public static void main(String[] args) throws IOException { 9 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); 10 | String operation = bufferedReader.readLine(); 11 | if(operation.equalsIgnoreCase("addition")) 12 | { 13 | float num1 = 7.5F, num2 = 10.5F; 14 | Context context = new Context(new Addition()); 15 | System.out.println("Addition: "+context.executeStrategy(num1, num2)); 16 | } 17 | System.out.print("Please enter first number: "); 18 | float num1 = Float.parseFloat(bufferedReader.readLine()); 19 | System.out.print("Please enter second number: "); 20 | float num2 = Float.parseFloat(bufferedReader.readLine()); 21 | Context context = new Context(new Addition()); 22 | System.out.println("Addition: "+context.executeStrategy(num1, num2)); 23 | 24 | context = new Context(new Substraction()); 25 | System.out.println("Substraction: "+context.executeStrategy(num1, num2)); 26 | 27 | context = new Context(new Multiplication()); 28 | System.out.println("Multiplication: "+context.executeStrategy(num1, num2)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/strategy/Multiplication.java: -------------------------------------------------------------------------------- 1 | package strategy; 2 | 3 | public class Multiplication implements Strategy{ 4 | @Override 5 | public float calculation(float a, float b) { 6 | return a * b; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/strategy/Strategy.java: -------------------------------------------------------------------------------- 1 | package strategy; 2 | 3 | public interface Strategy { 4 | public float calculation(float a, float b); 5 | } 6 | -------------------------------------------------------------------------------- /src/strategy/Substraction.java: -------------------------------------------------------------------------------- 1 | package strategy; 2 | 3 | public class Substraction implements Strategy{ 4 | @Override 5 | public float calculation(float a, float b) { 6 | return a-b; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/strategy/WithoutPattern.java: -------------------------------------------------------------------------------- 1 | package strategy; 2 | 3 | public class WithoutPattern { 4 | 5 | public double executeCalculation(String type,double a,double b) 6 | { 7 | if(type.equalsIgnoreCase("addition")){ 8 | return add(a, b); 9 | }else if(type.equalsIgnoreCase("subtraction")){ 10 | return subtract(a, b); 11 | }else if(type.equalsIgnoreCase("multiplication")){ 12 | return muliply(a, b); 13 | }else if(type.equalsIgnoreCase("devision")){ 14 | return devide(a, b); 15 | } 16 | return 1; 17 | } 18 | 19 | public double add(double a, double b) 20 | { 21 | return a + b; 22 | } 23 | 24 | public double subtract(double a, double b) 25 | { 26 | return a - b; 27 | } 28 | 29 | public double muliply(double a, double b) 30 | { 31 | return a * b; 32 | } 33 | 34 | public double devide(double a, double b) 35 | { 36 | return a/b; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/template/CaffeineBeverage.java: -------------------------------------------------------------------------------- 1 | package template; 2 | 3 | public abstract class CaffeineBeverage { 4 | final void prepareRecipe(){ 5 | boilWater(); 6 | brew(); 7 | pourIncup(); 8 | addCondiments(); 9 | } 10 | 11 | abstract void brew(); 12 | abstract void addCondiments(); 13 | 14 | void boilWater(){ 15 | System.out.println("Boiling water..."); 16 | } 17 | 18 | void pourIncup(){ 19 | System.out.println("Pouring into cup..."); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/template/CaffeineHouse.java: -------------------------------------------------------------------------------- 1 | package template; 2 | 3 | public class CaffeineHouse { 4 | public static void main(String[] args) { 5 | Tea tea = new Tea(); 6 | System.out.println("---------making tea------------"); 7 | tea.prepareRecipe(); 8 | Coffee coffee = new Coffee(); 9 | System.out.println("---------making coffee------------"); 10 | coffee.prepareRecipe(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/template/Coffee.java: -------------------------------------------------------------------------------- 1 | package template; 2 | 3 | public class Coffee extends CaffeineBeverage{ 4 | @Override 5 | void brew() { 6 | System.out.println("Dripping Coffee through filter..."); 7 | } 8 | 9 | @Override 10 | void addCondiments() { 11 | System.out.println("Adding sugar and milk"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/template/Tea.java: -------------------------------------------------------------------------------- 1 | package template; 2 | 3 | public class Tea extends CaffeineBeverage{ 4 | @Override 5 | void brew() { 6 | System.out.println("Stepping the tea..."); 7 | } 8 | 9 | @Override 10 | void addCondiments() { 11 | System.out.println("Adding lemon..."); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/template/template.md: -------------------------------------------------------------------------------- 1 | # Template Pattern 2 | 3 | **Template Pattern** ফাংশনের কাঠামো তৈরি করে এবং সাব -ক্লাসকে এই ফাংশনের কাঠামো পরিবর্তন না করে কাজ কেমন হবে বা কিভাবে কাজ করবে তা নির্ধারণ করার সুযোগ দেয় । 4 | 5 | The Template Method Pattern defines the skeleton of an algorithm in a method, 6 | deferring some steps to subclasses. Template Method lets subclasses redefine certain 7 | steps of an algorithm without changing the algorithm’s structure. 8 | 9 | The Dependency Inversion Principle আমাদের শেখায়, কংক্রিট ক্লাস বাদ দিয়ে যত বেশী সম্ভব Abstraction ব্যবহার করতে 10 | 11 | The Hollywood Principle is a technique for building frameworks or components so 12 | that lower-level components can be hooked into the computation, but without creating dependencies between the 13 | lower-level components and the higher-level layers. 14 | 15 | # অনেক পড়া লেখা হইছে, এখন একটু ক্যাফেইন দরকার 16 | 17 | আপনি আর আপনার বন্ধু ভার্সিটির লাল টঙ্গে গিয়ে মামাকে বললেন মামা একটা চা আর একটা কফি দেন(যদিও লাল টঙ্গে কফি পাওয়া যায় না)। মামা সাথে সাথে চা এবং কফি বানানো শুরু করলো... 18 | 19 | # কফি 20 | 21 | ```java 22 | public class Coffee{ 23 | void prepareRecipe(){ 24 | boilWater(); 25 | brewCoffeeGrinds(); 26 | pourInCup(); 27 | addSugarAndMilk(); 28 | } 29 | 30 | public void boilWater(){ 31 | System.out.println("Boiling Water..."); 32 | } 33 | 34 | public void brewCoffeeGrinds(){ 35 | System.out.println("Dripping coffee through filter..."); 36 | } 37 | 38 | public void pourInCup(){ 39 | System.out.println("Pouring into cup..."); 40 | } 41 | 42 | public void addSugarAndMilk(){ 43 | System.out.println("Adding Sugar and Milk..."); 44 | } 45 | } 46 | ``` 47 | 48 | # চা 49 | 50 | ```java 51 | public class Tea{ 52 | void prepareRecipe(){ 53 | boilWater(); 54 | steepTeaBag(); 55 | pourInCup(); 56 | addLemon(); 57 | } 58 | 59 | public void boilWater(){ 60 | System.out.println("Boiling Water..."); 61 | } 62 | 63 | public void steepTeaBag(){ 64 | System.out.println("Steeping the tea..."); 65 | } 66 | 67 | public void pourInCup(){ 68 | System.out.println("Pouring into cup..."); 69 | } 70 | 71 | public void addLemon(){ 72 | System.out.println("Adding lemon ..."); 73 | } 74 | } 75 | ``` 76 | 77 |

মামা, এতো কোড ডুপ্লিকেশন কেন ?

78 |
    79 |
  • কফি brewing আর চা steeping এর মধ্যেতো তেমন কোন পার্থক্য নাই ।
  • 80 |
  • কফিতে দুধ এবং চিনি দেওয়া আর চাতে লেবু দেওয়া তো একইরকম কাজ ।
  • 81 |
82 | 83 | # চলেন ডুপ্লিকেশন কমাই 84 | 85 | ```java 86 | public abstract class CaffeineBeverage { 87 | final void prepareRecipe(){ 88 | boilWater(); 89 | brew(); 90 | pourIncup(); 91 | addCondiments(); 92 | } 93 | 94 | abstract void brew(); 95 | abstract void addCondiments(); 96 | 97 | void boilWater(){ 98 | System.out.println("Boiling water..."); 99 | } 100 | 101 | void pourIncup(){ 102 | System.out.println("Pouring into cup..."); 103 | } 104 | } 105 | ``` 106 | 107 |

এখানে CaffeineBeverage কিন্তু আপনাকে brew এবং addCondiments মেথডকে আপনার ইচ্ছে মতো ডিফাইন করতে দিচ্ছে

108 | # ক্লাস ডায়াগ্রাম 109 | 110 | 111 | # নতুন কফি 112 | 113 | ```java 114 | public class Coffee extends CaffeineBeverage{ 115 | @Override 116 | void brew() { 117 | System.out.println("Dripping Coffee through filter..."); 118 | } 119 | 120 | @Override 121 | void addCondiments() { 122 | System.out.println("Adding sugar and milk"); 123 | } 124 | } 125 | ``` 126 | 127 | # নতুন চা 128 | 129 | ```java 130 | public class Tea extends CaffeineBeverage{ 131 | @Override 132 | void brew() { 133 | System.out.println("Stepping the tea..."); 134 | } 135 | 136 | @Override 137 | void addCondiments() { 138 | System.out.println("Adding lemon..."); 139 | } 140 | } 141 | ``` 142 | 143 |

Tea এবং Coffee ক্লাস কিন্তু সুপার ক্লাস CaffeineBeverage এর brew এবং addCondiments এর কাঠামো পরিবর্তন না করেই এর কাজ ডিফাইন করে দিয়েছে।

144 | 145 | # চলেন কোড রান করি 146 | 147 | ```java 148 | public class CaffeineHouse { 149 | public static void main(String[] args) { 150 | Tea tea = new Tea(); 151 | System.out.println("---------making tea------------"); 152 | tea.prepareRecipe(); 153 | Coffee coffee = new Coffee(); 154 | System.out.println("---------making coffee------------"); 155 | coffee.prepareRecipe(); 156 | } 157 | } 158 | ``` 159 | 160 | # আউটপুট 161 | 162 | ``` 163 | ---------making tea------------ 164 | Boiling water... 165 | Stepping the tea... 166 | Pouring into cup... 167 | Adding lemon... 168 | ---------making coffee------------ 169 | Boiling water... 170 | Dripping Coffee through filter... 171 | Pouring into cup... 172 | Adding sugar and milk 173 | ``` 174 | -------------------------------------------------------------------------------- /src/template/template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhRumi/Design-Pattern/509be61d583b1aec3c7960f68864a91122b46519/src/template/template.png --------------------------------------------------------------------------------