{"id":16364198,"url":"https://github.com/hieuwu/design-pattern-practice","last_synced_at":"2026-01-28T23:32:41.312Z","repository":{"id":102949782,"uuid":"415840577","full_name":"hieuwu/design-pattern-practice","owner":"hieuwu","description":"Practice notes for problems and solutions learned from Head First Design Pattern book","archived":false,"fork":false,"pushed_at":"2023-06-12T15:07:23.000Z","size":266,"stargazers_count":17,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-10T21:08:32.820Z","etag":null,"topics":["design-patterns","head-first-design-patterns","practice-project"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hieuwu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-10-11T08:27:46.000Z","updated_at":"2025-09-20T07:32:00.000Z","dependencies_parsed_at":null,"dependency_job_id":"d9a14670-63cb-486a-9372-834c7dfcbc49","html_url":"https://github.com/hieuwu/design-pattern-practice","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hieuwu/design-pattern-practice","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hieuwu%2Fdesign-pattern-practice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hieuwu%2Fdesign-pattern-practice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hieuwu%2Fdesign-pattern-practice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hieuwu%2Fdesign-pattern-practice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hieuwu","download_url":"https://codeload.github.com/hieuwu/design-pattern-practice/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hieuwu%2Fdesign-pattern-practice/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28855141,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T22:56:21.783Z","status":"ssl_error","status_checked_at":"2026-01-28T22:56:00.861Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["design-patterns","head-first-design-patterns","practice-project"],"created_at":"2024-10-11T02:29:33.933Z","updated_at":"2026-01-28T23:32:41.306Z","avatar_url":"https://github.com/hieuwu.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# design-pattern-practice\nPractice notes for problems and solutions learned from Head First Design Pattern book\n\n [![In-progress](https://img.shields.io/badge/In-progress-%23FFac45.svg?\u0026style=for-the-badge\u0026logo=java\u0026logoColor=white\u0026color=yellow)](https://github.com/)\n\n\n\u003cdiv id='top'/\u003e \n\n*******\nTables of contents  \n 1. [Strategy Pattern](#strategypattern)\n 2. [Observer Pattern](#observerpattern)\n 3. [Decorator Pattern](#decoratorpattern)\n 4. [Factory Pattern](#factorypattern)\n 5. [Singleton Pattern](#singletonpattern)\n 6. [Command Pattern](#commandpattern)\n\n*******\n[Jump to end](#theend)\n\u003cdiv id='strategypattern'/\u003e \n\n# Strategy Pattern:\n\n**Get started:** Write a program to display a Duck and other kinds of duck. Basic action that a duck can perform is swim, quack and display\n\n**Naive approach:** Use OO basics like Inheritance, create a Duck then other kinds of duck inherits attributes, method and override it if needed.\n\nThe class diagram looks like:\n\n```mermaid\n\nclassDiagram\n    Duck \u003c|-- OtherKindsOfDuck\n    Duck \u003c|-- MallardDuck\n    Duck \u003c|-- RedheadDuck\n\n    class Duck{\n      +swim()\n      +quack()\n      +display()\n    }\n    class OtherKindsOfDuck{\n        +display()\n    }\n    class MallardDuck{\n        +display()\n    }\n    class RedheadDuck{\n        +display()\n    }\n\n```\n\n\n**What if ..? :**\n- The customer wants to add a Rubber Duck.  It's ok, just override all the methods then leave it empty\n- The customer wants to add new action to a duck, like fly. We can add fly method to Duck class, and we forget to override this method in 33 subclass of Duck that can not fly. Big problem here!\n- The customer wants different duck to quack differently, We have to override quack in every Duck subclass?\n\n**Another approach:**\n- Use Interface `Quackable` and `Flyable`. Which type of duck can flly or quack can implement from theese interfaces but this is still not a good approach.\n- This approach looks good at first, but not good for mantainance. When we need to modify a behavior, we need to track and change it in all subclasses, this can lead to new bug.\n\n```mermaid\nclassDiagram\n    Duck \u003c|-- RubberDuck\n    Duck \u003c|-- MallardDuck\n    Duck \u003c|-- RedheadDuck\n        Quackable \u003c.. RedheadDuck\n    Quackable \u003c.. MallardDuck\n\n    class Duck{\n      +swim()\n      +quack()\n      +display()\n    }\n    class RubberDuck{\n        +display()\n    }\n    class MallardDuck{\n        +display()\n        +quack()\n    }\n    class RedheadDuck{\n        +display()\n        +fly()\n        +quack()\n    }\n\n    class Quackable{\n        \u003c\u003cinterface\u003e\u003e\n        +quack()\n    }\n\n    Flyable \u003c.. RedheadDuck\n    class Flyable{\n        \u003c\u003cinterface\u003e\u003e\n        +fly()\n    }\n\n```\n\n\u003c!-- [![](https://mermaid.ink/img/eyJjb2RlIjoiY2xhc3NEaWFncmFtXG4gICAgRHVjayA8fC0tIFJ1YmJlckR1Y2tcbiAgICBEdWNrIDx8LS0gTWFsbGFyZER1Y2tcbiAgICBEdWNrIDx8LS0gUmVkaGVhZER1Y2tcbiAgICAgICAgUXVhY2thYmxlIDwuLiBSZWRoZWFkRHVja1xuICAgIFF1YWNrYWJsZSA8Li4gTWFsbGFyZER1Y2tcblxuICAgIGNsYXNzIER1Y2t7XG4gICAgICArc3dpbSgpXG4gICAgICArcXVhY2soKVxuICAgICAgK2Rpc3BsYXkoKVxuICAgIH1cbiAgICBjbGFzcyBSdWJiZXJEdWNre1xuICAgICAgICArZGlzcGxheSgpXG4gICAgfVxuICAgIGNsYXNzIE1hbGxhcmREdWNre1xuICAgICAgICArZGlzcGxheSgpXG4gICAgICAgICtxdWFjaygpXG4gICAgfVxuICAgIGNsYXNzIFJlZGhlYWREdWNre1xuICAgICAgICArZGlzcGxheSgpXG4gICAgICAgICtmbHkoKVxuICAgICAgICArcXVhY2soKVxuICAgIH1cblxuICAgIGNsYXNzIFF1YWNrYWJsZXtcbiAgICAgICAgPDxpbnRlcmZhY2U-PlxuICAgICAgICArcXVhY2soKVxuICAgIH1cblxuICAgIEZseWFibGUgPC4uIFJlZGhlYWREdWNrXG4gICAgY2xhc3MgRmx5YWJsZXtcbiAgICAgICAgPDxpbnRlcmZhY2U-PlxuICAgICAgICArZmx5KClcbiAgICB9XG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlLCJhdXRvU3luYyI6dHJ1ZSwidXBkYXRlRGlhZ3JhbSI6ZmFsc2V9)](https://mermaid-js.github.io/mermaid-live-editor/edit/#eyJjb2RlIjoiY2xhc3NEaWFncmFtXG4gICAgRHVjayA8fC0tIFJ1YmJlckR1Y2tcbiAgICBEdWNrIDx8LS0gTWFsbGFyZER1Y2tcbiAgICBEdWNrIDx8LS0gUmVkaGVhZER1Y2tcbiAgICAgICAgUXVhY2thYmxlIDwuLiBSZWRoZWFkRHVja1xuICAgIFF1YWNrYWJsZSA8Li4gTWFsbGFyZER1Y2tcblxuICAgIGNsYXNzIER1Y2t7XG4gICAgICArc3dpbSgpXG4gICAgICArcXVhY2soKVxuICAgICAgK2Rpc3BsYXkoKVxuICAgIH1cbiAgICBjbGFzcyBSdWJiZXJEdWNre1xuICAgICAgICArZGlzcGxheSgpXG4gICAgfVxuICAgIGNsYXNzIE1hbGxhcmREdWNre1xuICAgICAgICArZGlzcGxheSgpXG4gICAgICAgICtxdWFjaygpXG4gICAgfVxuICAgIGNsYXNzIFJlZGhlYWREdWNre1xuICAgICAgICArZGlzcGxheSgpXG4gICAgICAgICtmbHkoKVxuICAgICAgICArcXVhY2soKVxuICAgIH1cblxuICAgIGNsYXNzIFF1YWNrYWJsZXtcbiAgICAgICAgPDxpbnRlcmZhY2U-PlxuICAgICAgICArcXVhY2soKVxuICAgIH1cblxuICAgIEZseWFibGUgPC4uIFJlZGhlYWREdWNrXG4gICAgY2xhc3MgRmx5YWJsZXtcbiAgICAgICAgPDxpbnRlcmZhY2U-PlxuICAgICAgICArZmx5KClcbiAgICB9XG4iLCJtZXJtYWlkIjoie1xuICBcInRoZW1lXCI6IFwiZGVmYXVsdFwiXG59IiwidXBkYXRlRWRpdG9yIjpmYWxzZSwiYXV0b1N5bmMiOnRydWUsInVwZGF0ZURpYWdyYW0iOmZhbHNlfQ) --\u003e\n\n**Efficient approach:**\n- We will delegate our Duck methods to another class, and interface so that our program would be less code reuse but, more flexible and maintainable (Following some Design Principles noted at the end of this section)\n- Create interfaces for behaviors like FlyBehavior, QuackBehavior. Then for each specific behavior, we create a class that implements the interface. Next, add a reference of each behavior inside a kind of Duck.\n- Our final result:\n\n```mermaid\n\nclassDiagram\n    Duck \u003c|-- RubberDuck\n    Duck \u003c|-- MallardDuck\n    Duck \u003c|-- RedheadDuck\n\n    class Duck{\n        -FlyBehavior flyBehavior\n        -QuackBehavior quackBehavior\n      +swim()\n      +quack()\n      +display()\n      +setFlyBehavior()\n      +setQuackBehavior()\n    }\n    \n    class RubberDuck{\n        +display()\n    }\n    \n    class MallardDuck{\n        +display()\n        +quack()\n    }\n    \n    class RedheadDuck{\n        +display()\n        +fly()\n        +quack()\n    }\n    FlyBehavior \u003c.. FlyWithWings\n    FlyBehavior \u003c.. FlyNoWay\n\n    class FlyBehavior{\n        \u003c\u003cinterface\u003e\u003e\n        +fly()\n    }\n\n    class FlyWithWings{\n        +fly()\n    }\n\n    class FlyNoWay{\n        +fly()\n    }\n\n    \n    QuackBehavior \u003c.. Quack\n    QuackBehavior \u003c.. Squeak\n\n    class QuackBehavior{\n        \u003c\u003cinterface\u003e\u003e\n        +fly()\n    }\n\n    class Quack{\n        +quack()\n    }\n\n    class Squeak{\n        +quack()\n    }\n\n```\n\n\n**Conclusion:**\n- **The Strategy Pattern** defines a family of algorithms,encapsulates each one, and makes them interchangeable.Strategy lets the algorithm vary independently from clients that use it\n\n[Back to top](#top)\n\n\u003cdiv id='observerpattern'/\u003e \n\n# Observer Pattern:\n**Get started:** Given that we need to write a Weather monitor application. In this application, we have to get data from a provider. The important thing is that, we need to notify to all users whenver the forecase measurement data is updated. And also we need to display it with in multiple forms.\n\n**Naive approach:** So first of all, we need a class contains the data and some methods to get and display data to the user. The class would look like:\n\n```mermaid\nclassDiagram\n\n    class WeatherData{\n        -CurrentConditionDisplay currentConditionDisplay\n        -StatisticsDisplay statisticsDisplay\n        -ForecastDisplay forecastDisplay\n      +getTemprature()\n      +getHumidity()\n      +getPressure()\n      +measurementsDataChanged()\n    }\n```\n\nAnd our `measurementsDataChanged` method would look something like:\n\n```java\npublic void measurementsDataChanged() {\n    float temp = getTemperature()\n    float humidity = getHumidity()\n    float pressure = getPressure()\n    \n    currentConditionDisplay.update(temp, humidity, pressure)\n    statisticsDisplay.update(temp, humidity, pressure)\n    forecastDisplay.update(temp, humidity, pressure)\n}\n```\n\n\n**What if ..? :** \n- We need to add more display or remove one. Because the `measurementsDataChanged()` method is implemented in concrete way, we can not add or remove display withou making changes to the program\n\n**Efficient approach:** We use Observer Pattern for this case. In this pattern, we will have a `Subject` which is our `WeatherData` class, where we get data from. The next one is `Observers`, all the thing that consume the data which is our displays\n- First, we need to define all the interface needed for `Observers`, `Subjects` along with shared behavior of each observer:\n```mermaid\nclassDiagram\n    class Subject{\n        \u003c\u003cinterface\u003e\u003e\n        +registerObserver(Observer o)\n        +removeObserver(Observer o)\n        +notifyObservers()\n    }\n\n    class Observer{\n        \u003c\u003cinterface\u003e\u003e\n        +update(float temp, float humidity, float pressure)\n    }\n\n    class DisplayElement{\n        \u003c\u003cinterface\u003e\u003e\n        +display()\n    }\n\n```\n- Next, refactor our `WeatherData` class:\n```java\npublic class WeatherData implements Subject {\n    private ArrayList observers;\n    private float temperature;\n    private float humidity;\n    private float pressure;\n    \n    public WeatherData() {\n        observers = new ArrayList();\n    }\n    \n    public void registerObserver(Observer o) {\n        observers.add(o);\n    }\n    \n    public void removeObserver(Observer o) {\n        int i = observers.indexOf(o);\n        if (i \u003e= 0) {\n            observers.remove(i);\n        }\n    }\n    \n    public void notifyObservers() {\n        for (int i = 0; i \u003c observers.size(); i++) {\n            Observer observer = (Observer) observers.get(i);\n            observer.update(temperature, humidity, pressure);\n        }\n    }\n    \n    public void measurementsChanged() {\n        notifyObservers();\n    }\n    public void setMeasurements(float temperature, float humidity, float pressure) {\n        this.temperature = temperature;\n        this.humidity = humidity;\n        this.pressure = pressure;\n        measurementsChanged();\n    }\n}\n```\n\n\n- Our final result:\n\n```mermaid\nclassDiagram\n    WeatherData \u003c|-- Subject\n    class WeatherData{\n        -CurrentConditionDisplay currentConditionDisplay\n        -StatisticsDisplay statisticsDisplay\n        -ForecastDisplay forecastDisplay\n      +getTemprature()\n      +getHumidity()\n      +getPressure()\n      +measurementsDataChanged()\n      +registerObserver(Observer o)\n      +removeObserver(Observer o)\n      +notifyObservers()\n    }\n    class Subject{\n        \u003c\u003cinterface\u003e\u003e\n        +registerObserver(Observer o)\n        +removeObserver(Observer o)\n        +notifyObservers()\n    }\n\n    class Observer{\n        \u003c\u003cinterface\u003e\u003e\n        +update(float temp, float humidity, float pressure)\n    }\n\n    class DisplayElement{\n        \u003c\u003cinterface\u003e\u003e\n        +display()\n    }\n\n    CurrentConditionDisplay \u003c|-- Observer\n    CurrentConditionDisplay \u003c|-- DisplayElement\n    class CurrentConditionDisplay {\n       +update(float temp, float humidity, float pressure)\n       +display()\n    }\n\n    StatisticsDisplay \u003c|-- Observer\n    StatisticsDisplay \u003c|-- DisplayElement\n    class StatisticsDisplay {\n       +update(float temp, float humidity, float pressure)\n       +display()\n    }\n\n    ForecastDisplay \u003c|-- Observer\n    ForecastDisplay \u003c|-- DisplayElement\n    class ForecastDisplay {\n       +update(float temp, float humidity, float pressure)\n       +display()\n    }\n```\n**Conclusion:**\n- **The Observer Pattern** defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically\n\n[Back to top](#top)\n\n\u003cdiv id='decoratorpattern'/\u003e\n\n# Decorator Pattern:\n**Get started:** Write a program to for a coffee shop to create order with many beverages, of course, many toppings and other properties are added onto each beverage.\n\n**Naive approach:** Create an abstract class called Beverage, and other kind will extends this class. Then just override methods like cost() to calculate the price for each kind of beverage.\n\nThe class diagram looks like:\n```mermaid\nclassDiagram\n    class Beverage{\n        -String description\n      +getDescription()\n      +cost()\n    }\n\n    Beverage \u003c|-- HouseBlend\n    class HouseBlend{\n      +cost()\n    }\n\n    Beverage \u003c|-- DarkRoast\n    class DarkRoast{\n      +cost()\n    }\n\n    Beverage \u003c|-- Decaf\n    class Decaf{\n      +cost()\n    }\n\n    \n    Beverage \u003c|-- Espresso\n    class Espresso{\n      +cost()\n    }\n```\n\n**What if ..? :**\n- We want to add some condiments like milk, chocolate, then we just need to create more class for this kind of \"new\" beverage. Maybe for current Coffee type, we would have new classes such as CoffeeWithMilk, CoffeeWithSoy,..**uh oh Class Explosion**\n- We calculate the price for each beverage, with different condiments, size\n\n**Another approach:** \n- Put all the condiments inside the abstract Beverage class, then for each subclass, we have to override all the checking condiments method as below. This is still not a good approach\n\n```mermaid\nclassDiagram\n    class Beverage{\n        -String description\n        -Condiment milk\n        -Condiment mocha\n        -Condiment soy\n        -Condiment whip\n      +getDescription()\n      +cost()\n      +hasMilk()\n      +setMilk()\n      +hasMocha()\n      +setMocha()\n      +hasWhip()\n      +setWhip()\n    }\n\n    Beverage \u003c|-- HouseBlend\n    class HouseBlend{\n      +cost()\n    }\n\n    Beverage \u003c|-- DarkRoast\n    class DarkRoast{\n      +cost()\n    }\n\n    Beverage \u003c|-- Decaf\n    class Decaf{\n      +cost()\n    }\n\n    Beverage \u003c|-- Espresso\n    class Espresso{\n      +cost()\n    }\n```\n- Our `cost()` method in `Beverage` class would look like:\n```java\npublic double cost() {\n    double condimentCost = 0.0\n    if (hasMilk()) {\n        condimentCost += milk.getCost()\n    }\n    \n    if (hasMocha()) {\n        coondimentCost += mocha.getCost()\n    }\n    return condimentCost\n}\n```\n\n- OUr `cost()` method in concreate class lets say `DarkRoast` would loook like:\n\n```java\npublic double cost() {\n    return 1.99 + super.cost()\n}\n```\n\n**Efficient approach:** WE will use the Decorator Pattern. The core concept of this pattern would look like:\n```mermaid\nclassDiagram\nclass Component{\n      +methodA()\n      +methodB()\n    }\n\n    Component \u003c|-- ConcreteComponent\n    class ConcreteComponent{\n      +methodA()\n      +methodB()\n    }\n\n    Component \u003c|-- Decorator\n    class Decorator{\n      +methodA()\n      +methodB()\n    }\n\n    Decorator \u003c|-- ConcreteDecoratorA\n    class ConcreteDecoratorA{\n      +methodA()\n      +methodB()\n    }\n\n    Decorator \u003c|-- ConcreteDecoratorB\n    class ConcreteDecoratorB{\n      +methodA()\n      +methodB()\n    }\n```\n- When we apply to our current design, it would look like:\n```mermaid\nclassDiagram\n    class Beverage{\n        -String description\n      +cost()\n      +getDescription()\n    }\n\n    Beverage \u003c|-- HouseBlend\n    class HouseBlend{\n      +cost()\n    }\n\n    Beverage \u003c|-- Espresso\n    class Espresso{\n      +cost()\n    }\n\n    Beverage \u003c|-- DarkRoast\n    class DarkRoast{\n      +cost()\n    }\n\n    Beverage \u003c|-- CondimentDecorator\n    class CondimentDecorator{\n      +getDescription()\n    }\n\n    CondimentDecorator \u003c|-- Milk\n    class Milk{\n        -Beverage beverage\n      +cost()\n      +getDescription()\n    }\n\n    CondimentDecorator \u003c|-- Mocha\n    class Mocha{\n        -Beverage beverage\n      +cost()\n      +getDescription()\n    }\n\n    CondimentDecorator \u003c|-- Soy\n    class Soy{\n        -Beverage beverage\n      +cost()\n      +getDescription()\n    }\n\n    CondimentDecorator \u003c|-- Whip\n    class Whip{\n        -Beverage beverage\n      +cost()\n      +getDescription()\n    }\n```\n\n- Here is how we actually use this pattern in code:\n\n```java\npublic abstract class Beverage {\n    String description = “Unknown Beverage”;\n    public String getDescription() {\n        return description;\n    }\n    public abstract double cost();\n}\n\npublic abstract class CondimentDecorator extends Beverage {\n    public abstract String getDescription();\n}\n```\n- Our concrete beverages:\n```java\npublic class Espresso extends Beverage {\n    public Espresso() {\n        description = “Espresso”;\n    }\n    public double cost() {\n        return 1.99;\n    }\n}\n```\n\n```java\npublic class HouseBlend extends Beverage {\n    public HouseBlend() {\n        description = “House Blend Coffee”;\n    }\n    public double cost() {\n        return .89;\n    }\n}\n```\n- Our condiment decorator\n```java\npublic class Mocha extends CondimentDecorator {\n    Beverage beverage;\n    public Mocha(Beverage beverage) {\n        this.beverage = beverage;\n    }\n    public String getDescription() {\n        return beverage.getDescription() + “, Mocha”;\n    }\n    public double cost() {\n        return .20 + beverage.cost();\n    }\n}\n```\n- And finally how we decorate objects in runtime:\n```java\n    public static void main(String args[]) {\n        Beverage beverage = new Espresso();\n        System.out.println(beverage.getDescription() +\n            “$” + beverage.cost());\n        Beverage beverage2 = new DarkRoast();\n        beverage2 = new Mocha(beverage2);\n        beverage2 = new Mocha(beverage2);\n        beverage2 = new Whip(beverage2);\n        System.out.println(beverage2.getDescription() +\n            “$” + beverage2.cost());\n        Beverage beverage3 = new HouseBlend();\n        beverage3 = new Soy(beverage3);\n        beverage3 = new Mocha(beverage3);\n        beverage3 = new Whip(beverage3);\n        System.out.println(beverage3.getDescription() +\n            “$” + beverage3.cost());\n    }\n```\n- The output looks like:\n\n```\nEspresso $1.99\nDark Roast Coffee, Mocha, Mocha, Whip $1.49\nHouse Blend Coffee, Soy, Mocha, Whip $1.34\n```\n\n[Back to top](#top)\n\n\u003cdiv id='factorypattern'/\u003e\n\n# Factory Pattern:\n- Simple Factory\n- Factory Method\n- Abstract Factory\n\n**Get started:** Write a program to support a pizza shop make their order process mroe smooth. This program supports creating many types of Pizza and be able to customized based on branches.\n\n\n**Naive approach:** As usual, we will come up with a `orderPizza` function like this, because to order a pizza, we need some mroe steps like prepare, bake, cut,... so we have:\n\n```java\nPizza orderPizza(){\n    Pizza pizza = new Pizza();\n    \n    pizza.perpare();\n    pizza.bake();\n    pizze,cut();\n    pizza.box();\n    return pizza;\n}\n```\n\nThe class diagram looks like:\n\n**What if ..? :**\n- We need to add more pizze types. Then our `orderPizza` becomes:\n```java\nPizza orderPizza(String type){\n    Pizza pizza;\n    \n    if (type.equals(\"cheese\") pizza = new CheesePizza();\n    else if (type.equals(\"geekl\") pizza = new GeekPizza();\n    else if (type.equals(\"cheese\") pizza = new CheesePizza();\n    else if (type.equals(\"clam\") pizza = new ClamPizza();\n\n    pizza.perpare();\n    pizza.bake();\n    pizze,cut();\n    pizza.box();\n    return pizza;\n}\n```\n\n**Another approach:**\n- We can improve the code inside `orderPizza` function. AS you can see, we can separate the code for creating a pizza based on its type. Put the creation code to a separated class, and we have a simple factory. **This is not actually a Design Pattern but commonly used**\n```java\npublic class SimplePizzaFactory {\n\n    public Pizza createPizza(String type) {\n        Pizza pizza;\n    \n        if (type.equals(\"cheese\") pizza = new CheesePizza();\n        else if (type.equals(\"geekl\") pizza = new GeekPizza();\n        else if (type.equals(\"cheese\") pizza = new CheesePizza();\n        else if (type.equals(\"clam\") pizza = new ClamPizza();\n\n        return pizza; \n    }\n}\n```\n\n- The code for the PizzaStore class would look like:\n\n```java\npublic class PizzaStore {\n    SimplePizzaFactory factory;\n    public PizzaStore(SimplePizzaFactory factory) {\n        this.factory = factory;\n    }\n    public Pizza orderPizza(String type) {\n        Pizza pizza;\n        \n        pizza = factory.createPizza(type);\n        pizza.perpare();\n        pizza.bake();\n        pizze,cut();\n        pizza.box();\n        \n        return pizza;\n    }\n    \n}\n```\n- The class diagram looks like:\n\n```mermaid\nclassDiagram\n    SimplePizzaFactory *-- PizzaStore\n    class PizzaStore{\n        -SimplePizzaFactory factory\n      +orderPizza()\n    }\n\n    class Pizza{\n      +prepare()\n      +bake()\n      +cut()\n      +box()\n    }\n\n    Pizza \u003c|-- CheesePizza\n    class CheesePizza{\n    } \n\n    Pizza \u003c|-- GeekPizza\n    class GeekPizza{\n    }\n\n    Pizza \u003c|-- PeperoniPizza\n    class PeperoniPizza{\n    }\n\n    Pizza \u003c-- SimplePizzaFactory\n    class SimplePizzaFactory{\n        -Pizza factory\n      +createPizza()\n    }\n\n    class SimplePizzaFactory{\n        -Pizza factory\n      +createPizza()\n    }\n\n```\n**Problem occurs:**\n- When we need to fanchise our PizzaStore to many places with many different types of Pizza. For example. New York style pizza, Chicago style Pizza. Now we need to build a framework to create the right type of pizza and also keep our process smooth. Because our Pizza Store is already stable.\n- A naive approach is that we can create factory object for each fanchise. For example: NYPizzaFactory, ChicagoPizzaFactory and whenever we need, just `new NYPizzaFactory()`\n\n**Better approach** \n- Make our PizzaStore class and the `createPizza` method  `abstract` as well. Because our ordering process is stable so we just keep it as usual. If you want every fanchise has the same process, make it `final`.\n- Implement orderPizze method \n- Create other franchise pizza factory by subclass from PizzaStore, and override the createPizza method. Because our createrPizze is abstract, we force all concreate class override it and let subclass decide what type of pizza they create.\nThe code:\n```java\npublic abstract class PizzaStore {\n    public Pizza orderPizza(String type) {\n        Pizza pizza;\n        \n        pizza = factory.createPizza(type);\n        pizza.perpare();\n        pizza.bake();\n        pizze,cut();\n        pizza.box();\n        \n        return pizza;\n    }\n    \n    abstract Pizza createPizza(String type);\n    \n}\n```\n\n- Class diagram for franchise would look like:\n\n```mermaid\nclassDiagram\n    class PizzaStore{\n      +createPizza()\n      +orderPizza()\n    }\n\n    PizzaStore \u003c|-- NewYorkStylePizzaStore\n    class NewYorkStylePizzaStore{\n      +createPizza()\n    }\n\n    PizzaStore \u003c|-- ChicagoStylePizzaStore\n    class ChicagoStylePizzaStore{\n      +createPizza()\n    }\n```\n- In each subclass of PizzaStore, let's say ChicagoStylePizzaStore, the `createPizze` method would look like:\n\n```java\npublic class ChicagoStylePizzaStore extends PizzaStore {\n  Pizza createPizza(String item) {\n    if (item.equals(“cheese”)) {\n      return new NYStyleCheesePizza();\n    } else if (item.equals(“veggie”)) {\n      return new NYStyleVeggiePizza();\n    } else if (item.equals(“clam”)) {\n      return new NYStyleClamPizza();\n    } else if (item.equals(“pepperoni”)) {\n      return new NYStylePepperoniPizza();\n    } else return null;\n  }\n}\n```\nThe `createPizza` method above is called Factory method. Which is:\n- Abstract so that the subclass is counted to handle object creation\n- Returns data type used within methods declare in the superclass\n- Isolates the code in superclass from knowing what kind of object is actually created\n\n**Efficient approach:** Currently, our Pizza Store is fine. However, it is very hard to keep the ingredients of the pizza in every store at different regions the same. For example, the New Your store would use another ingredients for the tomato sauce, the Chicago store also do so. This is when we need to do something to make our ingredients set more flexible across region.\nBecause of the fact that New York would use one set of ingredients, Chicago would use another. It's time we need to create families of ingredients.\nFirst, we need to create an IngredientsFactory to create each set of ingredients. If our stores in every region have the same behavior, consider using an `abstract` class. In this case, an `interface` is good enough. Our shared factory would look like:\n\n```java\npublic interface PizzaIngredientFactory {\n    public Dough createDough();\n    public Sauce createSauce();\n    public Cheese createCheese();\n    public Veggies[] createVeggies();\n    public Pepperoni createPepperoni();\n    public Clams createClam();\n}\n```\nNext, we need to:\n- Build factory for each region\n- Implement set of ingredients class to be used with the factory\n- Hook the new factories to current Pizza Store \n\nLet's take the New York style for an example:\n```java\npublic class NYPizzaIngredientFactory implements PizzaIngredientFactory {\n    public Dough createDough() {\n        return new ThinCrustDough();\n    }\n    public Sauce createSauce() {\n        return new MarinaraSauce();\n    }\n    public Cheese createCheese() {\n        return new ReggianoCheese();\n    }\n    public Veggies[] createVeggies() {\n        Veggies veggies[] = {\n            new Garlic(),\n            new Onion(),\n            new Mushroom(),\n            new RedPepper()\n        };\n        return veggies;\n    }\n    public Pepperoni createPepperoni() {\n        return new SlicedPepperoni();\n    }\n    public Clams createClam() {\n        return new FreshClams();\n    }\n}\n```\nRemember that all the classed that being created should be the concrete class of the return type :)\nAfter that, our Pizza class becomes:\n\n```java\npublic abstract class Pizza {\n    String name;\n    Dough dough;\n    Sauce sauce;\n    Veggies veggies[];\n    Cheese cheese;\n    Pepperoni pepperoni;\n    Clams clam;\n    abstract void prepare();\n    void bake() {\n        System.out.println(“Bake for 25 minutes at 350”);\n    }\n    void cut() {\n        System.out.println(“Cutting the pizza into diagonal slices”);\n    }\n    void box() {\n        System.out.println(“Place pizza in official PizzaStore box”);\n    }\n}\n```\nNow that we have an abstraction of Pizza. So clean! Let's take a look on it's concrete classes:\n```java\npublic class CheesePizza extends Pizza {\n    PizzaIngredientFactory ingredientFactory;\n    public CheesePizza(PizzaIngredientFactory ingredientFactory) {\n        this.ingredientFactory = ingredientFactory;\n    }\n    void prepare() {\n        System.out.println(“Preparing“ + name);\n        dough = ingredientFactory.createDough();\n        sauce = ingredientFactory.createSauce();\n        cheese = ingredientFactory.createCheese();\n    }\n}\n\n\npublic class ClamPizza extends Pizza {\n    PizzaIngredientFactory ingredientFactory;\n    public ClamPizza(PizzaIngredientFactory ingredientFactory) {\n        this.ingredientFactory = ingredientFactory;\n    }\n    void prepare() {\n        System.out.println(“Preparing“ + name);\n        dough = ingredientFactory.createDough();\n        sauce = ingredientFactory.createSauce();\n        cheese = ingredientFactory.createCheese();\n        clam = ingredientFactory.createClam();\n    }\n}\n\n```\n\n\n**Conclusion:**\n- **The Factory Method Pattern**: defines an interface for creating object but let subclass decide which class to instantiate.\n- **Dependency Inversion Principle**: depends uppon abstractions. Do not depend on concrete classes\n\n\u003e **Note**: Guildline to follow Dependency Inversion Principle:\n\u003e - No variable should hold a reference to a concrete class (If use `new`, which means holding a reference to concrete class. Should delegate to a factory)\n\u003e - No class should derive from concrete class (If we derive from concrete class, we depends on it. Only depends on abstractions like abstract class or interface)\n\u003e - No method should override implemented method of base class (If we override implemented method, the base class wasn't really an abstraction anymore. Those implemented methods are meant to be shared by all subclasses)\n\n[Back to top](#top)\n\n\u003cdiv id='singletonpattern'/\u003e \n\n# Singleton Pattern:\n**Get started:** We need to create an object to be used everywhere. Make sure this object is one-of-a-kind.\n\n**Naive approach:** Create a class as the diagram below. Because we only need our object is only initialized when we need it, then we check null before returning initialize it. So simple:\n```mermaid\nclassDiagram\n    class Singleton{\n      - uniqueInstance: Singleton\n      +getInstance(): Singleton\n    }\n```\n\n```java\npublic class Singleton {\n    private static Singleton uniqueInstance;\n    // other useful instance variables here\n    private Singleton() {}\n    public static Singleton getInstance() {\n        if (uniqueInstance == null) {\n            uniqueInstance = new Singleton();\n        }\n        return uniqueInstance;\n    }\n    // other useful methods here\n}\n```\n**Problem occurs:**\n- What if we have more than one place use the singleton at the same time? More than one thread access to properties of the Singleton.\n- How do we handle this case? Some threads would have some conditions for the properties from Singleton to make the program run properly. Value of a property might be modified by a process while another is about to use the previous value.\n- If we do not handle this case for multi threads, it would lead to the situation where one thread always run wrongly and never give us the expected behavior\n\n**Better approach:** We need to do something to make sure that 'if a thread is about to access singleton, every other threads that access before should done their job'.\nWe can do this by using `synchronized` keyword in Java:\n\n```java\npublic class Singleton {\n    private static Singleton uniqueInstance;\n    // other useful instance variables here\n    private Singleton() {}\n    public static synchronized Singleton getInstance() {\n        if (uniqueInstance == null) {\n            uniqueInstance = new Singleton();\n        }\n        return uniqueInstance;\n    }\n    // other useful methods here\n}\n```\n\u003e **Note**: The `synchronized` is only relevent by the time we initlaized the object. When we already have the object, we do not need to synchronize this method. Looks like synchronized is unnedded overhead\n\n**Efficient approach**: We have 3 options to consider to make sure our Singleton object works properly for every cases including multithreading one.\n1. Keep the `synchronized` and leave the current one as is if the object initalization is not expensive to your application\n2. Move to an eagerly created instance rather than a lazily one. \nUsing this approach, we rely on the JVM to create the unique instance of the Singleton when the class is loaded. The JVM guarantees that the instance will be created before any thread accesses the static uniqueInstance variable\n```java\npublic class Singleton {\n    private static Singleton uniqueInstance = new Singleton();\n    private Singleton() {}\n    public static Singleton getInstance() {\n        return uniqueInstance;\n    }\n}\n```\n3. Use “double-checked locking” to reduce the use of synchronization in getInstance()\nWith double-checked locking, we first check to see if an instance is created, and if not, THEN we\nsynchronize. This way, we only synchronize the first time through, just what we want\n```java\npublic class Singleton {\n    private volatile static Singleton uniqueInstance;\n    private Singleton() {}\n    public static Singleton getInstance() {\n        if (uniqueInstance == null) {\n            synchronized(Singleton.class) {\n                if (uniqueInstance == null) {\n                    uniqueInstance = new Singleton();\n                }\n            }\n        }\n        return uniqueInstance;\n    }\n}\n```\n\u003e **Note**: The volatile keyword ensures that multiple threads handle the uniqueInstance variable correctly when it is being initialized to the Singleton instance\n\n**Conclusion:**\n- **The Singleton Pattern** : ensures a class has only one instance, and provides a global point of access to it\n\n\n[Back to top](#top)\n\n\u003cdiv id='commandpattern'/\u003e \n\n# Command Pattern:\n**Get started:** Given that we want to build an API to support a remote control to control our smart home devices. This API would allow the remote to interact with the classes provided by the devices vendor. In general, this control will have some slots, each slot would allow you to control a device. For each device, you can perform turn on, turn off and other actions.\nThe classes provided are something like:\n\n**Initial thought**: With OO Principles in our hands, our initial though is that we should do something to make sure that the remote does not know much about the details of how to turn on or turn off a light. It should request throught another helper to make it do it.\nWe also need to avoid if statements like `if slot1 == Light then turnOff() else if slot1 == GarageDoor then scrollDown()`. This approach will lead to lot of changes when we need to add more devices. More work and more bugs.\n\n**Approach:** Alright, now we have to do some thing to make the remote coltrol requests for what it want and another helper make the work done. This is quite similar to the way we request an order in restaurant. Let's take this as an example before we jump in to the pattern.\nThe order process looks like:\n```mermaid\nflowchart LR\n    Customer-- createOrder --\u003eWaitress --takeOrder, orderUp--\u003eCook--makeBurger, makeDrink --\u003eDish             \n```\nThe waitress will receive order from customer, then bring it to the Cook, tell him to cook. After that, the cook will make the dishes following the list inside the order.\nBack to our case, the remote control need to create requests to `another class` to execute, and inside the execute of `another class`, we will call the exact method of each class provided from vendors.\nLet's take a look at this diagram:\n\n```mermaid\nclassDiagram\n\n    Receiver \u003c-- Client\n    ConcreteCommand \u003c-- Client\n    class Client{\n    }\n\n    Receiver \u003c-- ConcreteCommand\n    class Receiver{\n    }\n\n    Command \u003c-- Invoker\n    class Invoker{\n    }\n\n    class Command{\n        \u003c\u003cinterface\u003e\u003e\n        +execute()\n        +undo()\n    }\n    Command \u003c.. ConcreteCommand\n    class ConcreteCommand{\n        +execute()\n        +undo()\n    }\n```\nIn general, this is how it works:\n\n```mermaid\nflowchart LR\n    Client-- createCommandObject, setCommand --\u003e Invoker --execute--\u003e Receiver           \n```\n\n[Back to top](#top)\n\n\u003cdiv id='adapterandfacadepattern'/\u003e \n# Adapter and Facade Pattern:\n\n\n\u003cdiv id='theend'/\u003e \n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhieuwu%2Fdesign-pattern-practice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhieuwu%2Fdesign-pattern-practice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhieuwu%2Fdesign-pattern-practice/lists"}