Chain of responsibility

 

Motivation :-

The idea of this pattern is to decouple senders and receivers by giving multiple objects a chance to handle a request. The request gets passed along a chain of objects until one of them handles it. The first object in the chain receives the request and either handles it or forwards it to the next candidate on the chain, which does likewise. The object that made the request has no explicit knowledge of who will handle it.

ChainOfResponsibility

 

When you should use this :-

This pattern is recommended when either of the following scenarios occur in your application –

1. You want to issue a request to one of several objects without specifying the receiver explicitly.
2. Multiple objects can handle a request. The handler should be ascertained in the runtime automatically.
3. A request not being handled is an acceptable outcome.

 

Practical usage of the pattern –

1. The pattern is used in windows systems to handle events generated from the keyboard or mouse.
2. Exception handling systems also implement this pattern, with the runtime checking if a handler is provided for the exception through the call stack. If no handler is defined, the exception will cause a crash in the program, as it is unhandled.
3. In JavaEE, the concept of Servlet filters implement the Chain of Responsibility pattern, and may also decorate the request to add extra information before the request is handled by a servlet.

 

Sample Code :-

Chain Of Responsibility

Abstract rule handler –

package com.sanjit;

import java.util.Map;

import com.sanjit.rule.Rule;

/**
 * Abstract rule handler class.
 *
 * @author Sanjit Mohanty
 * @version 0.1
 *
 *
 * Revision History:
 * VERSION DATE AUTHOR COMMENT
 * 0.1 20-May-2015 Sanjit Mohanty initial create
 *
 *
 */

public abstract class RuleHandler {
protected RuleHandler nextRuleHandler;

public RuleHandler() {
nextRuleHandler = null;
}

public void setNextRuleHandler(RuleHandler nextRuleHandler) {
this.nextRuleHandler = nextRuleHandler;
}

protected abstract boolean canHandle(Rule rule);
protected abstract Map<String, String> processRule(Rule rule);

public Map<String, String> populateRuleData(Rule rule) {

Map<String, String> result;

if (canHandle(rule)) {
result = processRule(rule);
} else {
if (null != nextRuleHandler) {
result = nextRuleHandler.populateRuleData(rule);
} else {
result = new UnknownRuleHandler().process(rule);
}
}
return result;
}

}

First concrete rule handler –


package com.sanjit;

import java.util.HashMap;
import java.util.Map;

import com.sanjit.rule.Rule;

/**
 * Concrete rule handler 1 class.
 *
 * @author Sanjit Mohanty
 * @version 0.1
 *
 *
 * Revision History:
 * VERSION DATE AUTHOR COMMENT
 * 0.1 20-May-2015 Sanjit Mohanty initial create
 *
 *
 */
public class ConcreteRuleHandler1 extends RuleHandler {

@Override
protected Map<String, String> process(Rule rule){
 Map<String, String> ruleData = new HashMap<String, String>();

 // Your processing logic goes here...
 return ruleData;
 }

 @Override
 protected boolean canHandle(Rule rule) {
 // TODO Auto-generated method stub
 return (rule instanceof ConcreteRuleHandler1);
 }
}

Second concrete rule handler –

package com.sanjit;

/**
 * Concrete rule handler 2 class.
 *
 * @author Sanjit Mohanty
 * @version 0.1
 *
 *
 * Revision History:
 * VERSION DATE AUTHOR COMMENT
 * 0.1 20-May-2015 Sanjit Mohanty initial create
 *
 *
 */
public class ConcreteRuleHandler2 extends RuleHandler {

@Override
protected Map<String, String> process(Rule rule){
 Map<String, String> ruleData = new HashMap<String, String>();

 // Your processing logic goes here...
 return ruleData;
 }

 @Override
 protected boolean canHandle(Rule rule) {
 // TODO Auto-generated method stub
 return (rule instanceof ConcreteRuleHandler2);
 }
}

Third concrete rule handler –

package com.sanjit;

/**
 * Concrete rule handler 3 class.
 *
 * @author Sanjit Mohanty
 * @version 0.1
 *
 *
 * Revision History:
 * VERSION DATE AUTHOR COMMENT
 * 0.1 20-May-2015 Sanjit Mohanty initial create
 *
 *
 */
public class ConcreteRuleHandler3 extends RuleHandler {

@Override
protected Map<String, String> process(Rule rule){
 Map<String, String> ruleData = new HashMap<String, String>();

 // Your processing logic goes here...
 return ruleData;
 }

 @Override
 protected boolean canHandle(Rule rule) {
 // TODO Auto-generated method stub
 return (rule instanceof ConcreteRuleHandler3);
 }
}

Client class –


package com.sanjit;

import java.util.Map;
import com.sanjit.rule.Rule;

/**
 * Client class.
 *
 * @author Sanjit Mohanty
 * @version 0.1
 *
 *
 * Revision History:
 * VERSION DATE AUTHOR COMMENT
 * 0.1 20-May-2015 Sanjit Mohanty initial create
 *
 *
 */

public class RuleClient {

private ConcreteRuleHandler1 concreteRuleHandler1 = null;
private ConcreteRuleHandler2 concreteRuleHandler2 = null;
private ConcreteRuleHandler3 concreteRuleHandler3 = null;

public RuleClient () {
super();

 // TODO Auto-generated constructor stub
concreteRuleHandler1 = new ConcreteRuleHandler1();
concreteRuleHandler2 = new ConcreteRuleHandler2();
concreteRuleHandler3 = new ConcreteRuleHandler3();

concreteRuleHandler1.setNextRuleHandler(concreteRuleHandler2);
concreteRuleHandler2.setNextRuleHandler(concreteRuleHandler3);
}

 private void populateRuleSpecificValues(Rule rule) {
 Map<String, String> ruleData = null;

 RuleHandler ruleHandler = concreteRuleHandler1;
ruleData = ruleHandler.populateRuleData(rule);
 }
}
Advertisements

Behavioral Design Pattern – The Strategy Pattern

Strategy Pattern is one of the behavioral design pattern which defines a set of encapsulated algorithms that can be swapped to carry out a specific behavior at runtime without causing tight coupling. It is also known as Policy Pattern.

The Strategy pattern is to be used where you want to choose the algorithm to use at runtime.

One of the example of this pattern is Collection.sort() method that takes Comparator parameter. Based on different implementations of Comparator interfaces, the Objects are getting sorted in different ways.

On the downside, clients must be aware of different Strategies. The pattern has a potential drawback in that a client must understand how Strategies differ before it can select the appropriate one. Clients might be exposed to implementation issues. Therefore you should use the Strategy pattern only when the variation in behavior is relevant to clients.

Let’s try to illustrate the pattern with an example. Below is the class diagram for ease of reference –

classdiagram

First of all we will create the interface for our strategy:


package com.sanjit;

public interface OnlinePaymentStrategy {

public void pay(double amount);

}

Now we will have to create concrete implementations of algorithms for payment using netbanking/credit card:


package com.sanjit;

public class NetbankingPaymentStrategy implements OnlinePaymentStrategy {

/* (non-Javadoc)

* @see com.sanjit.OnlinePaymentStrategy#pay(double)

*/

@Override

public void pay(double amount) {

/*

* Logic for payment through netbanking goes here..

*/

System.out.println("Pay - " + amount + " through netbanking");

}

}

And now credit card strategy:


package com.sanjit;

public class CreditCardPaymentStrategy implements OnlinePaymentStrategy {

/* (non-Javadoc)

* @see com.sanjit.OnlinePaymentStrategy#pay(double)

*/

@Override

public void pay(double amount) {

/*

* Logic for payment through credit card goes here..

*/

System.out.println("Pay - " + amount + " through credit card");

}

}

Now our algorithms are ready and we can implement shopping item & cart. The payment method will require input as Payment strategy:


package com.sanjit;

public class ShoppingItem {

private int qty;

private double price;

public int getQty() {

return qty;

}

public void setQty(int qty) {

this.qty = qty;

}

public double getPrice() {

return price;

}

public void setPrice(double price) {

this.price = price;

}

}

The shopping cart:


package com.sanjit;

import java.util.List;

public class Cart {

private List<ShoppingItem> items;

public List<ShoppingItem> getItems() {

return items;

}

public void setItems(List<ShoppingItem> items) {

this.items = items;

}

public double calculateCartPrice() {

double cartPrice = 0;

for (ShoppingItem item : items) {

cartPrice += item.getQty() * item.getPrice();

}

return cartPrice;

}

public void pay(OnlinePaymentStrategy ops) {

ops.pay(calculateCartPrice());

}

}

Now the main class for test purpose:-


package com.sanjit;

import java.util.ArrayList;

import java.util.List;

public class Main {

/**

* @param args

*/

public static void main(String[] args) {

List<ShoppingItem> itemList = new ArrayList<ShoppingItem>();

ShoppingItem item1 = new ShoppingItem();

item1.setQty(10);

item1.setPrice(100);

itemList.add(item1);

ShoppingItem item2 = new ShoppingItem();

item2.setQty(5);

item2.setPrice(10);

itemList.add(item2);

Cart cart = new Cart();

cart.setItems(itemList);

//Pay by credit card

cart.pay(new CreditCardPaymentStrategy());

//Pay by netbanking

cart.pay(new NetbankingPaymentStrategy());

}

}

Output on running the Main class:

Pay – 1050.0 through credit card

Pay – 1050.0 through netbanking

Behavioral Design Pattern – The Visitor Pattern

Visitor Pattern is one of the behavioral design pattern which is used when we have to manage algorithms, relationships & responsibilities on a group of similar kind of objects at runtime, thus decoupling the operations from the object’s structure. So, Visitor pattern can provide additional functionality to a class without actually changing it.

The pattern should be used when you have distinct & unrelated operations to perform across a structure of objects. This avoids adding in code throughout your object structure that is better kept separate, so it encourages cleaner code. In summary, if you want to decouple some logical code from the elements that you’re using as input, visitor is probably the best pattern for the job.

On the downside, the arguments & return types for the visiting methods needs to be known in advance, so the Visitor pattern is not good for situations where these visited classes are subject to change. Every time a new type of Element is added, every Visitor derived class must be amended.

Also, it can be difficult to refactor the Visitor pattern into code that wasn’t already designed with the pattern in mind. And, when you do add your Visitor code, it can look obscure. The Visitor is powerful, but you should make sure to use it only when necessary.

Let’s try to illustrate the pattern with an example. Below is the class diagram for ease of reference –

classdiagram_1

First, let’s create our general visitable  interface:


package com.sanjit;

public interface ShoppingItem {
      public void accept(Visitor visitor);
}

  

Now, we’ll create a concrete implementation of our interface, Games :


package com.sanjit;

public class Games implements ShoppingItem {

      private double price;
      private int qty;

      public double getPrice() {
            return price;
      }

      public void setPrice(double price) {
            this.price = price;
      }

      public int getQty() {
            return qty;
      }

      public void setQty(int qty) {
            this.qty = qty;
      }

      @Override
      public void accept(Visitor visitor) {
            visitor.visit(this);
      }
}

  

and now for the Music:


package com.sanjit;

public class Music implements ShoppingItem {

      private double price;
      private int qty;

      public double getPrice() {
            return price;
      }

      public void setPrice(double price) {
            this.price = price;
      }

      public int getQty() {
            return qty;
      }

      public void setQty(int qty) {
            this.qty = qty;
      }

      @Override
      public void accept(Visitor visitor) {
            visitor.visit(this);
      }
}

As you can see it’s just a simple POJO, with the extra accept method added to allow the visitor access to the element. We could add in other types here to handle other items.

Now we’ll move on to the Visitor interface. For each different type of concrete element here, we’ll need to add a visit method. As we’ll just deal with Games & Music for now, this is as simple as:


package com.sanjit;

public interface Visitor {
      void visit(Games items);
      void visit(Music items);
}

The implementation of the Visitor can then deal with the specifics of what to do when we visit a Game or Music.


package com.sanjit;

public class CartVisitor implements Visitor {

      private double cartCost;

      public double getCartCost() {
            return cartCost;
      }

      public void setCartCost(double cartCost) {
            this.cartCost = cartCost;
      }

      @Override
      public void visit(Music items) {
         cartCost += items.getQty() * items.getPrice();
      }

      @Override
      public void visit(Games items) {
            cartCost += items.getQty() * items.getPrice();
      }
}

As you can see it’s a simple formula, but the point is that all the calculation for cart is done in one central place.

To drive this visitor, we’ll need a way of iterating through our shopping cart, as follows:


package com.sanjit;

import java.util.List;

public class Cart {

      private List<ShoppingItem> items;

      public List<ShoppingItem> getItems() {
            return items;
      }

      public void setItems(List<ShoppingItem> items) {
            this.items = items;
      }

      public void calculateCartPrice() {

            CartVisitor cartVisitor = new CartVisitor();

            for(ShoppingItem item:items){
                  item.accept(cartVisitor);
            }

            System.out.println("Total Cart Cost: " + cartVisitor.getCartCost());
      }
}

Note that if we had other types of item here, once the visitor implements a method to visit that item, we could easily calculate the total cart cost.

The whole point of this pattern is to allow you separate out certain logic from the elements themselves, keeping your data classes simple.

Now the main class for test purpose:-


package com.sanjit;

import java.util.ArrayList;

import java.util.List;

public class Main {

          public static void main(String[] args) {

            Music m = new Music();
            m.setPrice(50);
            m.setQty(10);

            Games g = new Games();
            g.setPrice(100);
            g.setQty(100);

            List<ShoppingItem> items = new ArrayList<ShoppingItem>();
            items.add(m);
            items.add(g);

            Cart cart = new Cart();
            cart.setItems(items);
            cart.calculateCartPrice();
      }

}

Output on running the Main class:

Total Cart Cost: 10500.0