Tuesday 9 January 2018

Design Patterns | Decorator design pattern

The decorator design pattern is used to enhance the functionality/responsibility of a particular object at run-time or dynamically. It applies when there is a need to dynamically add as well as remove responsibilities to a class, and when sub-classing would be impossible due to a large number of sub-classes that could result.

The decorator design pattern is based on abstract classes and we derive concrete implementation from those classes.

At the same time, other instance of the same class will not be affected by this so individual object gets the new behavior.

Implementation of the Decorator pattern 

Coffee making scenario

Coffee.java
/**
 * The interface Coffee defines the functionality of Coffee implemented by decorator
 * @author rajesh.dixit
 */
public interface Coffee {
     
    /** @return Returns the cost of the coffee.*/
    public double getCost();
   
    /** @return Returns the ingredients of the coffee */
    public String getIngredients();
}

SimpleCoffee.java
/**
 * Extension of a simple coffee without any extra ingredients
 * @author rajesh.dixit
 */
public class SimpleCoffee implements Coffee {

      @Override
      public double getCost() {
            return 1;
      }

      @Override
      public String getIngredients() {
            return "Coffee";
      }
}

CoffeeDecorator.java
/**
 * Abstract decorator class - note that it implements Coffee interface
 * @author rajesh.dixit
 */
public abstract class CoffeeDecorator implements Coffee {
      protected final Coffee decoratedCoffee;

      public CoffeeDecorator(Coffee c) {
            this.decoratedCoffee = c;
      }

      /** Implementing methods of the interface. */
      public double getCost() {
            return decoratedCoffee.getCost();
      }

      public String getIngredients() {
            return decoratedCoffee.getIngredients();
      }
}


/**
 * Decorator WithMilk mixes milk into coffee.
 * Note it extends CoffeeDecorator.
 * @author rajesh.dixit
 */
class WithMilk extends CoffeeDecorator {
      public WithMilk(Coffee c) {
            super(c);
      }

      /** Overriding methods defined in the abstract superclass */
      public double getCost() {
            return super.getCost() + 0.5;
      }

      public String getIngredients() {
            return super.getIngredients() + ", Milk";
      }
}


/**
 * Decorator WithSprinkles mixes sprinkles onto coffee.
 * Note it extends CoffeeDecorator.
 * @author rajesh.dixit
 */
class WithSprinkles extends CoffeeDecorator {
      public WithSprinkles(Coffee c) {
            super(c);
      }

      public double getCost() {
            return super.getCost() + 0.2;
      }

      public String getIngredients() {
            return super.getIngredients() + ", Sprinkles";
      }
}

TestDecorator.java
public class TestDecorator {

      public static void main(String[] args) {
            Coffee c = new SimpleCoffee();
            print(c);

            c = new WithMilk(c);
            print(c);

            c = new WithSprinkles(c);
            print(c);
      }

      public static void print(Coffee c) {
            System.out.println("Cost: " + c.getCost() + "; Ingredients: "
                        + c.getIngredients());
      }
}

Output:
Cost: 1.0; Ingredients: Coffee
Cost: 1.5; Ingredients: Coffee, Milk
Cost: 1.7; Ingredients: Coffee, Milk, Sprinkles

Usage in Java Libraries
1. All subclasses of java.io.InputStream, OutputStream, Reader, and Writer have a constructor taking an instance of the same type.

2. java.util.Collections, the checkedXXX(), synchronizedXXX() and unmodifiableXXX() methods.

3. javax.servlet.http.HttpServletRequestWrapper and HttpServletResponseWrapper.

4. 
Graphical User Interface Frameworks
GUI toolkits use decoration pattern to add functionalities dynamically as explained before.

5. In Mobiquity, to load all ValidationService and MComService and decorate them as business rules(TCP, PIN Check and All).

Reference

Design Patterns | Observer pattern or Publish-subscribe pattern

The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

It is mainly used to implement distributed event handling systems, in "event-driven" software.


In the observer pattern, the objects that watch on the state of another object are called Observers and the object that is being watched is called Subject. The Subject maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.


Let's assume we have a channel on YouTube which is subscribed by many users. Now any new video uploaded on that channel should be notified to all subscribers by SMS or mail alerts.

In Observer pattern, we need to separate the subject (YouTube channel) from its observers (Subscribers) in such a way that adding new observer (Subscription for the new user) will be transparent for the server.

import java.util.ArrayList;
import java.util.List;

public interface Observer {

    public void update();

    public void setSubject(Subject subject);
}

public interface Subject {

    public void registerObserver(Observer observer);

    public void notifyObserver();

    public void unRegisterObserver(Observer observer);

    public String getUpdate();
}

public class YouTubeChannel implements Subject {

    List<Observer> observersList;
    private boolean stateChange;

    public YouTubeChannel() {
        this.observersList = new ArrayList<Observer>();
        stateChange = false;
    }

    public void registerObserver(Observer observer) {
        observersList.add(observer);
    }

    public void unRegisterObserver(Observer observer) {
        observersList.remove(observer);
    }

    public void notifyObserver() {

        if (stateChange) {
            for (Observer observer : observersList) {
                observer.update();
            }
        }
    }

    public String getUpdate() {
        String changedState = null;
        // should have logic to send the
        // state change to querying observer
        if (stateChange) {
            changedState = "Observer Design Pattern";
        }
        return changedState;
    }

    public void postNewArticle() {
        stateChange = true;
        notifyObserver();
    }
}

public class User implements Observer {
    public User(String userName) {
        this.userName = userName;
    }

    private String userName;

    private String article;
    private Subject youtubeChan;

    public void setSubject(Subject youtubeChan) {
        this.youtubeChan = youtubeChan;
        article = "No New Article!";
    }

    @Override
    public void update() {
        System.out.println("State change reported by Subject " + userName);
        article = youtubeChan.getUpdate();
    }

    public String getArticle() {
        return article;
    }
}

public class ObserverPatternTest {
    public static void main(String args[]) {
        YouTubeChannel blog = new YouTubeChannel();
        User user1 = new User("user 1");
        User user2 = new User("user 2");

        blog.registerObserver(user1);
        blog.registerObserver(user2);

        user1.setSubject(blog);
        user2.setSubject(blog);

        System.out.println(user1.getArticle());
        blog.postNewArticle();
        System.out.println(user1.getArticle());
    }
}
Output:
No New Article!
State change reported by Subject to user 1
State change reported by Subject to user 2
Observer Design Pattern

Usage of Observer design pattern
Java Message Service (JMS) uses Observer pattern along with Mediator pattern to allow applications to subscribe and publish data to other applications.

MVC frameworks also use Observer pattern where Model is the Subject and Views are observers that can register to get notified of any change to the model.

The observer pattern is implemented in numerous programming libraries and systems, including almost all GUI toolkits.

Java provides an inbuilt platform for implementing Observer pattern through java.util.Observable class and java.util.Observer interface.


Related Posts Plugin for WordPress, Blogger...