Tuesday, May 4, 2010

Visitor Pattern

The visitor pattern is a behavioral object design pattern. The visitor pattern is used to simplify operations on groupings of related objects. These operations are performed by the visitor rather than by placing this code in the classes being visited. Since the operations are performed by the visitor rather than by the classes being visited, the operation code gets centralized in the visitor rather than being spread out across the grouping of objects, thus leading to code maintainability. The visitor pattern also avoids the use of the instanceof operator in order to perform calculations on similar classes.
In the visitor pattern, we have a Visitor interface that declares visit() methods for the various types of elements that can be visited. Concrete Visitors implement the Visitor interface's visit() methods. The visit() methods are the operations that should be performed by the visitor on an element being visited.
The related classes that will be visited implement an Element interface that declares an accept() method that takes a visitor as an argument. Concrete Elements implement the Element interface and implement the accept() method. In the accept() method, the visitor's visit() method is called with 'this', the current object of the Concrete Element type.
The elements to visit all implement the accept() method that takes a visitor as an argument. In this method, they call the visitor's visit() method with 'this'. As a result of this, an element takes a visitor and then the visitor performs its operation on the element.
Let's illustrate the visitor pattern with an example. First, we'll define a NumberVisitor interface. This interface declares three visit methods which take different types as arguments. Note that if we only wrote one visit method, we'd have to use the instanceof operator or a similar technique to handle the different element types. However, since we have separate visit methods, we don't need the instanceof operator, since each visit method handles a different type.

NumberVisitor.java

package com.cakes;

import java.util.List;

public interface NumberVisitor {

 public void visit(TwoElement twoElement);

 public void visit(ThreeElement threeElement);

 public void visit(List elementList);

}
All of the elements classes to be visited will implement the NumberElement interface. This interface has a single method that takes a NumberVisitor as an argument.

NumberElement.java

package com.cakes;

public interface NumberElement {

 public void accept(NumberVisitor visitor);

}
Let's create a TwoElement class that implements NumberElement. It has two int fields. Its accept() method calls the visitor's visit() method with 'this'. The operator to be performed on TwoElement is performed by the visitor.

TwoElement.java

package com.cakes;

public class TwoElement implements NumberElement {

 int a;
 int b;

 public TwoElement(int a, int b) {
  this.a = a;
  this.b = b;
 }

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

}
The ThreeElement class is similar to TwoElement, except that it has three int fields.

ThreeElement.java

package com.cakes;

public class ThreeElement implements NumberElement {

 int a;
 int b;
 int c;

 public ThreeElement(int a, int b, int c) {
  this.a = a;
  this.b = b;
  this.c = c;
 }

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

}
Now, let's create a visitor called SumVisitor that implements the NumberVisitor interface. For TwoElement and ThreeElement objects, this visitor will sum up the int fields. For a List of NumElements (ie, TwoElement and ThreeElement objects), this visitor will iterate over the elements and call their accept() methods. As a result of this, the visitor will perform visit operations on all the TwoElement and ThreeElement objects that make up the list, since the call to accept() in turn calls the visitor's visit methods for the TwoElement and ThreeElement objects. 

SumVisitor.java

package com.cakes; import java.util.List; public class SumVisitor implements NumberVisitor { @Override public void visit(TwoElement twoElement) { int sum = twoElement.a + twoElement.b; System.out.println(twoElement.a + "+" + twoElement.b + "=" + sum); } @Override public void visit(ThreeElement threeElement) { int sum = threeElement.a + threeElement.b + threeElement.c; System.out.println(threeElement.a + "+" + threeElement.b + "+" + threeElement.c + "=" + sum); } @Override public void visit(List elementList) { for (NumberElement ne : elementList) { ne.accept(this); } } } Here is another visitor, TotalSumVisitor. In addition to summing up the int fields and displaying the sum, this visitor will keep track of the total sums of all the elements that are visited.

TotalSumVisitor.java

package com.cakes; import java.util.List; public class TotalSumVisitor implements NumberVisitor { int totalSum = 0; @Override public void visit(TwoElement twoElement) { int sum = twoElement.a + twoElement.b; System.out.println("Adding " + twoElement.a + "+" + twoElement.b + "=" + sum + " to total"); totalSum += sum; } @Override public void visit(ThreeElement threeElement) { int sum = threeElement.a + threeElement.b + threeElement.c; System.out.println("Adding " + threeElement.a + "+" + threeElement.b + "+" + threeElement.c + "=" + sum + " to total"); totalSum += sum; } @Override public void visit(List elementList) { for (NumberElement ne : elementList) { ne.accept(this); } } public int getTotalSum() { return totalSum; } } Let's see the visitor pattern in action. The Demo class creates two TwoElement objects and one ThreeElement object. It creates a list of NumberElements and adds the TwoElement object and the ThreeElement object to the list. Next, we create a SumVisitor and we visit the list with the SumVisitor. After this, we create a TotalSumVisitor and visit the list with the TotalSumVisitor. We display the total sum via the call to TotalSumVisitor's getTotalSum() method.

Demo.java

package com.cakes; import java.util.ArrayList; import java.util.List; public class Demo { public static void main(String[] args) { TwoElement two1 = new TwoElement(3, 3); TwoElement two2 = new TwoElement(2, 7); ThreeElement three1 = new ThreeElement(3, 4, 5); List numberElements = new ArrayList(); numberElements.add(two1); numberElements.add(two2); numberElements.add(three1); System.out.println("Visiting element list with SumVisitor"); NumberVisitor sumVisitor = new SumVisitor(); sumVisitor.visit(numberElements); System.out.println("\nVisiting element list with TotalSumVisitor"); TotalSumVisitor totalSumVisitor = new TotalSumVisitor(); totalSumVisitor.visit(numberElements); System.out.println("Total sum:" + totalSumVisitor.getTotalSum()); } } The console output of executing Demo is shown here.

Console Output

Visiting element list with SumVisitor 3+3=6 2+7=9 3+4+5=12 Visiting element list with TotalSumVisitor Adding 3+3=6 to total Adding 2+7=9 to total Adding 3+4+5=12 to total Total sum:27 Notice that if we'd like to perform new operations on the grouping of elements, all we would need to do is write a new visitor class. We would not have to make any additions to the existing element classes, since they provide the data but none of the code for the operations.

Template Method Pattern

The template method pattern is a behavioral class pattern. A behavioral class pattern uses inheritance for distribution of behavior. In the template method pattern, a method (the 'template method') defines the steps of an algorithm. The implementation of these steps (ie, methods) can be deferred to subclasses. Thus, a particular algorithm is defined in the template method, but the exact steps of this algorithm can be defined in subclasses. The template method is implemented in an abstract class. The steps (methods) of the algorithm are declared in the abstract class, and the methods whose implementations are to be delegated to subclasses are declared abstract.
Here is an example of the template method pattern. Meal is an abstract class with a template method called doMeal() that defines the steps involved in a meal. We declare the method as final so that it can't be overridden. The algorithm defined by doMeal() consists of four steps: prepareIngredients(), cook(), eat(), and cleanUp(). The eat() method is implemented although subclasses can override the implementation. The prepareIngredients(), cook(), and cleanUp() methods are are declared abstract so that subclasses need to implement them.

Meal.java

package com.cakes;

public abstract class Meal {

 // template method
 public final void doMeal() {
  prepareIngredients();
  cook();
  eat();
  cleanUp();
 }

 public abstract void prepareIngredients();

 public abstract void cook();

 public void eat() {
  System.out.println("Mmm, that's good");
 }

 public abstract void cleanUp();

}
The HamburgerMeal class extends Meal and implements Meal's three abstract methods.

HamburgerMeal.java

package com.cakes;

public class HamburgerMeal extends Meal {

 @Override
 public void prepareIngredients() {
  System.out.println("Getting burgers, buns, and french fries");
 }

 @Override
 public void cook() {
  System.out.println("Cooking burgers on grill and fries in oven");
 }

 @Override
 public void cleanUp() {
  System.out.println("Throwing away paper plates");
 }

}
The TacoMeal class implements Meal's three abstract methods and also overrides the eat() method.

TacoMeal.java

package com.cakes;

public class TacoMeal extends Meal {

 @Override
 public void prepareIngredients() {
  System.out.println("Getting ground beef and shells");
 }

 @Override
 public void cook() {
  System.out.println("Cooking ground beef in pan");
 }

 @Override
 public void eat() {
  System.out.println("The tacos are tasty");
 }

 @Override
 public void cleanUp() {
  System.out.println("Doing the dishes");
 }

}
The Demo class creates a HamburgerMeal object and calls its doMeal() method. It creates a TacoMeal object and calls doMeal() on the TacoMeal object.

Demo.java

package com.cakes;

public class Demo {

 public static void main(String[] args) {

  Meal meal1 = new HamburgerMeal();
  meal1.doMeal();

  System.out.println();

  Meal meal2 = new TacoMeal();
  meal2.doMeal();

 }

}
The console output of the execution of Demo is shown here.

Console Output

Getting burgers, buns, and french fries
Cooking burgers on grill and fries in oven
Mmm, that's good
Throwing away paper plates

Getting ground beef and shells
Cooking ground beef in pan
The tacos are tasty
Doing the dishes
As you can see, the template method design pattern allows us to define the steps in an algorithm and pass the implementation of these steps to subclasses.

Startergy Pattern

The strategy pattern is a behavioral object design pattern. In the strategy pattern, different algorithms are represented as Concrete Strategy classes, and they share a common Strategy interface. A Context object contains a reference to a Strategy. By changing the Context's Strategy, different behaviors can be obtained. Although these behaviors are different, the different strategies all operate on data from the Context.
The strategy pattern is one way that composition can be used as an alternative to subclassing. Rather than providing different behaviors via subclasses overriding methods in superclasses, the strategy pattern allows different behaviors to be placed in Concrete Strategy classes which share the common Strategy interface. A Context class is composed of a reference to a Strategy.
Here is an example of the strategy pattern. First, we'll define a Strategy interface. It declares a checkTemperature() method.

Strategy.java

package com.cakes;

public interface Strategy {

 boolean checkTemperature(int temperatureInF);

}
The HikeStrategy class is a concrete strategy class that implements the Strategy interface. The checkTemperature method is implemented so that if the temperature is between 50 and 90, it returns true. Otherwise it returns false.

HikeStrategy.java

package com.cakes;

public class HikeStrategy implements Strategy {

 @Override
 public boolean checkTemperature(int temperatureInF) {
  if ((temperatureInF >= 50) && (temperatureInF <= 90)) {
   return true;
  } else {
   return false;
  }
 }

}
The SkiStrategy implements the Strategy interface. If the temperature is 32 or less, the checkTemperature method returns true. Otherwise it returns false.

SkiStrategy.java

package com.cakes;

public class SkiStrategy implements Strategy {

 @Override
 public boolean checkTemperature(int temperatureInF) {
  if (temperatureInF <= 32) {
   return true;
  } else {
   return false;
  }
 }

}
The Context class contains a temperature and a reference to a Strategy. The Strategy can be changed, resulting in different behavior that operates on the same data in the Context. The result of this can be obtained from the Context via the getResult() method.

Context.java

package com.cakes;

public class Context {

 int temperatureInF;
 Strategy strategy;

 public Context(int temperatureInF, Strategy strategy) {
  this.temperatureInF = temperatureInF;
  this.strategy = strategy;
 }

 public void setStrategy(Strategy strategy) {
  this.strategy = strategy;
 }

 public int getTemperatureInF() {
  return temperatureInF;
 }

 public boolean getResult() {
  return strategy.checkTemperature(temperatureInF);
 }

}
The Demo class creates a Context object with a temperature of 60 and with a SkiStrategy. It displays the temperature from the context and whether that temperature is OK for skiing. After that, it sets the Strategy in the Context to HikeStrategy. It then displays the temperature from the context and whether that temperature is OK for hiking. 

Demo.java

package com.cakes; public class Demo { public static void main(String[] args) { int temperatureInF = 60; Strategy skiStrategy = new SkiStrategy(); Context context = new Context(temperatureInF, skiStrategy); System.out.println("Is the temperature (" + context.getTemperatureInF() + "F) good for skiing? " + context.getResult()); Strategy hikeStrategy = new HikeStrategy(); context.setStrategy(hikeStrategy); System.out.println("Is the temperature (" + context.getTemperatureInF() + "F) good for hiking? " + context.getResult()); } } The console output of executing Demo is shown here.

Console Output

Is the temperature (60F) good for skiing? false Is the temperature (60F) good for hiking? true

State Pattern

The state pattern is a behavioral object design pattern. The idea behind the state pattern is for an object to change its behavior depending on its state. In the state pattern, we have a Context class, and this class has a State reference to a Concrete State instance. The State interface declares particular methods that represent the behaviors of a particular state. Concrete States implement these behaviors. By changing a Context's Concrete State, we change its behavior. In essence, in the state pattern, a class (the Context) is supposed to behave like different classes depending on its state. The state pattern avoids the use of switch and if statements to change behavior.
Let's look at an example of the state pattern. First off, we'll define the EmotionalState interface. It declares two methods, sayHello() and sayGoodbye().

EmotionalState.java

package com.cakes;

// State
public interface EmotionalState {

 public String sayHello();

 public String sayGoodbye();

}
The HappyState class is a Concrete State that implements sayHello() and sayGoodbye() of EmotionalState. These messages are cheerful (representing a happy state).

HappyState.java

package com.cakes;

// Concrete State
public class HappyState implements EmotionalState {

 @Override
 public String sayGoodbye() {
  return "Bye, friend!";
 }

 @Override
 public String sayHello() {
  return "Hello, friend!";
 }

}
The SadState class also implements the EmotionalState interface. The messages are sad (representing a sad state).

SadState.java

package com.cakes;

//Concrete State
public class SadState implements EmotionalState {

 @Override
 public String sayGoodbye() {
  return "Bye. Sniff, sniff.";
 }

 @Override
 public String sayHello() {
  return "Hello. Sniff, sniff.";
 }

}
The Person class is the Context class. It contains an EmotionalState reference to a concrete state. In this example, we have Person implement the EmotionalState reference, and we pass the calls to Person's sayHello() and sayGoodbye() methods on to the corresponding methods on the emotionalState reference. As a result of this, a Person object behaves differently depending on the state of Person (ie, the current EmotionalState reference).

Person.java

package com.cakes;

// Context
public class Person implements EmotionalState {

 EmotionalState emotionalState;

 public Person(EmotionalState emotionalState) {
  this.emotionalState = emotionalState;
 }

 public void setEmotionalState(EmotionalState emotionalState) {
  this.emotionalState = emotionalState;
 }

 @Override
 public String sayGoodbye() {
  return emotionalState.sayGoodbye();
 }

 @Override
 public String sayHello() {
  return emotionalState.sayHello();
 }

}
The Demo class demonstrates the state pattern. First, it creates a Person object with a HappyState object. We display the results of sayHello() and sayGoodbyte() when the person object is in the happy state. Next, we change the person object's state with a SadState object. We display the results of sayHello() and sayGoodbyte(), and we see that in the sad state, the person object's behavior is different.

Demo.java

package com.cakes; public class Demo { public static void main(String[] args) { Person person = new Person(new HappyState()); System.out.println("Hello in happy state: " + person.sayHello()); System.out.println("Goodbye in happy state: " + person.sayGoodbye()); person.setEmotionalState(new SadState()); System.out.println("Hello in sad state: " + person.sayHello()); System.out.println("Goodbye in sad state: " + person.sayGoodbye()); } } The console output of executing Demo is shown here.

Console Output

Hello in happy state: Hello, friend! Goodbye in happy state: Bye, friend! Hello in sad state: Hello. Sniff, sniff. Goodbye in sad state: Bye. Sniff, sniff. Note that we don't necessarily need to have the Context (ie, Person) implement the EmotionalState interface. The behavioral changes could have been internal to the Context rather than exposing EmotionalState's methods to the outside. However, having the Context class implement the State interface allows us to directly access the different behaviors that result from the different states of the Context.

Observer Pattern

The observer pattern is a behavioral object design pattern. In the observer pattern, an object called the subject maintains a collection of objects called observers. When the subject changes, it notifies the observers. Observers can be added or removed from the collection of observers in the subject. The changes in state of the subject can be passed to the observers so that the observers can change their own state to reflect this change.
The subject has an interface that defines methods for attaching and detaching observers from the subject's collection of observers. This interface also features a notification method. This method should be called when the state of the subject changes. This notifies the observers that the subject's state has changed. The observers have an interface with a method to update the observer. This update method is called for each observer in the subject's notification method. Since this communication occurs via an interface, any concrete observer implementing the observer interface can be updated by the subject. This results in loose coupling between the subject and the observer classes.
Now we'll look at an example of the observer pattern. We'll start by creating an interface for the subject called WeatherSubject. This will declare three methods: addObserver(), removeObserver(), and doNotify().

WeatherSubject.java

package com.cakes;

public interface WeatherSubject {

 public void addObserver(WeatherObserver weatherObserver);

 public void removeObserver(WeatherObserver weatherObserver);

 public void doNotify();

}
We'll also create an interface for the observers called WeatherObserver. It features one method, a doUpdate() method.

WeatherObserver.java

package com.cakes;

public interface WeatherObserver {

 public void doUpdate(int temperature);
 
}
The WeatherStation class implements WeatherSubject. It is our subject class. It maintains a set of WeatherObservers which are added via addObserver() and removed via removeObserver(). When WeatherSubject's state changes via setTemperature(), the doNotify() method is called, which contacts all the WeatherObservers with the temperature via their doUpdate() methods.

WeatherStation.java

package com.cakes;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class WeatherStation implements WeatherSubject {

 Set weatherObservers;
 int temperature;

 public WeatherStation(int temperature) {
  weatherObservers = new HashSet();
  this.temperature = temperature;
 }

 @Override
 public void addObserver(WeatherObserver weatherObserver) {
  weatherObservers.add(weatherObserver);
 }

 @Override
 public void removeObserver(WeatherObserver weatherObserver) {
  weatherObservers.remove(weatherObserver);
 }

 @Override
 public void doNotify() {
  Iterator it = weatherObservers.iterator();
  while (it.hasNext()) {
   WeatherObserver weatherObserver = it.next();
   weatherObserver.doUpdate(temperature);
  }
 }

 public void setTemperature(int newTemperature) {
  System.out.println("\nWeather station setting temperature to " + newTemperature);
  temperature = newTemperature;
  doNotify();
 }

}
WeatherCustomer1 is an observer that implements WeatherObserver. Its doUpdate() method gets the current temperature from the WeatherStation and displays it.

WeatherCustomer1.java

package com.cakes; public class WeatherCustomer1 implements WeatherObserver { @Override public void doUpdate(int temperature) { System.out.println("Weather customer 1 just found out the temperature is:" + temperature); } } WeatherCustomer2 performs similar functionality as WeatherCustomer1.

WeatherCustomer2.java

package com.cakes; public class WeatherCustomer2 implements WeatherObserver { @Override public void doUpdate(int temperature) { System.out.println("Weather customer 2 just found out the temperature is:" + temperature); } } The Demo class demonstrates the observer pattern. It creates a WeatherStation and then a WeatherCustomer1 and a WeatherCustomer2. The two customers are added as observers to the weather station. Then the setTemperature() method of the weather station is called. This changes the state of the weather station and the customers are notified of this temperature update. Next, the WeatherCustomer1 object is removed from the station's collection of observers. Then, the setTemperature() method is called again. This results in the notification of the WeatherCustomer2 object.

Demo.java

package com.cakes; public class Demo { public static void main(String[] args) { WeatherStation weatherStation = new WeatherStation(33); WeatherCustomer1 wc1 = new WeatherCustomer1(); WeatherCustomer2 wc2 = new WeatherCustomer2(); weatherStation.addObserver(wc1); weatherStation.addObserver(wc2); weatherStation.setTemperature(34); weatherStation.removeObserver(wc1); weatherStation.setTemperature(35); } } The console output of executing Demo is shown here.

Console Output

Weather station setting temperature to 34 Weather customer 2 just found out the temperature is:34 Weather customer 1 just found out the temperature is:34 Weather station setting temperature to 35 Weather customer 2 just found out the temperature is:35 In a more advanced case, we might have given each observer a reference to the weather station object. This could allow the observer the ability to compare the state of the subject in detail with its own state and make any necessary updates to its own state.

Momento Pattern

The memento pattern is a behavioral design pattern. The memento pattern is used to store an object's state so that this state can be restored at a later point. The saved state data in the memento object is not accessible outside of the object to be saved and restored. This protects the integrity of the saved state data.
In this pattern, an Originator class represents the object whose state we would like to save. A Memento class represents an object to store the state of the Originator. The Memento class is typically a private inner class of the Originator. As a result, the Originator has access to the fields of the memento, but outside classes do not have access to these fields. This means that state information can be transferred between the Memento and the Originator within the Originator class, but outside classes do not have access to the state data stored in the Memento.
The memento pattern also utilizes a Caretaker class. This is the object that is responsible for storing and restoring the Originator's state via a Memento object. Since the Memento is a private inner class, the Memento class type is not visible to the Caretaker. As a result, the Memento object needs to be stored as an Object within the Caretaker.

Now, let's look at an example. The DietInfo class is our Originator class. We'd like to be able to save and restore its state. It contains 3 fields: a dieter name field, the day number of the diet, and the weight of the dieter on the specified day of the diet.
This class contains a private inner class called Memento. This is our Memento class that is used to save the state of DietInfo. Memento has 3 fields representing the dieter name, the day number, and the weight of the dieter.
Notice the save() method of DietInfo. This creates and returns a Memento object. This returned Memento object gets stored by the caretaker. Note that DietInfo.Memento is not visible, so the caretaker can't reference DietInfo.Memento. Instead, it stores the reference as an Object.
The restore() method of DietInfo is used to restore the state of the DietInfo. The caretaker passes in the Memento (as an Object). The memento is cast to a Memento object and then the DietInfo object's state is restored by copying over the values from the memento.

DietInfo.java

package com.cakes;

// originator - object whose state we want to save
public class DietInfo {

 String personName;
 int dayNumber;
 int weight;

 public DietInfo(String personName, int dayNumber, int weight) {
  this.personName = personName;
  this.dayNumber = dayNumber;
  this.weight = weight;
 }

 public String toString() {
  return "Name: " + personName + ", day number: " + dayNumber + ", weight: " + weight;
 }

 public void setDayNumberAndWeight(int dayNumber, int weight) {
  this.dayNumber = dayNumber;
  this.weight = weight;
 }

 public Memento save() {
  return new Memento(personName, dayNumber, weight);
 }

 public void restore(Object objMemento) {
  Memento memento = (Memento) objMemento;
  personName = memento.mementoPersonName;
  dayNumber = memento.mementoDayNumber;
  weight = memento.mementoWeight;
 }

 // memento - object that stores the saved state of the originator
 private class Memento {
  String mementoPersonName;
  int mementoDayNumber;
  int mementoWeight;

  public Memento(String personName, int dayNumber, int weight) {
   mementoPersonName = personName;
   mementoDayNumber = dayNumber;
   mementoWeight = weight;
  }
 }
}
DietInfoCaretaker is the caretaker class that is used to store the state (ie, the memento) of a DietInfo object (ie, the originator). The memento is stored as an object since DietInfo.Memento is not visible to the caretaker. This protects the integrity of the data stored in the Memento object. The caretaker's saveState() method saves the state of the DietInfo object. The caretaker's restoreState() method restores the state of the DietInfo object.

DietInfoCaretaker.java

package com.cakes;

// caretaker - saves and restores a DietInfo object's state via a memento
// note that DietInfo.Memento isn't visible to the caretaker so we need to cast the memento to Object
public class DietInfoCaretaker {

 Object objMemento;

 public void saveState(DietInfo dietInfo) {
  objMemento = dietInfo.save();
 }

 public void restoreState(DietInfo dietInfo) {
  dietInfo.restore(objMemento);
 }

}
 
he MementoDemo class demonstrates the memento pattern. It creates a
caretaker and then a DietInfo object. The DietInfo object's state is
changed and displayed. At one point, the caretaker saves the state of
the DietInfo object. After this, the DietInfo object's state is further
changed and displayed. After this, the caretaker restores the state of
the DietInfo object. We verify this restoration by displaying the
DietInfo object's state. 

MementoDemo.java

package com.cakes; public class MementoDemo { public static void main(String[] args) { // caretaker DietInfoCaretaker dietInfoCaretaker = new DietInfoCaretaker(); // originator DietInfo dietInfo = new DietInfo("Fred", 1, 100); System.out.println(dietInfo); dietInfo.setDayNumberAndWeight(2, 99); System.out.println(dietInfo); System.out.println("Saving state."); dietInfoCaretaker.saveState(dietInfo); dietInfo.setDayNumberAndWeight(3, 98); System.out.println(dietInfo); dietInfo.setDayNumberAndWeight(4, 97); System.out.println(dietInfo); System.out.println("Restoring saved state."); dietInfoCaretaker.restoreState(dietInfo); System.out.println(dietInfo); } } The console output of the execution of MementoDemo is shown here. Notice how the state changes, and how we are able to save and restore the state of the originator via the caretaker's reference to the memento.

Console Output

Name: Fred, day number: 1, weight: 100 Name: Fred, day number: 2, weight: 99 Saving state. Name: Fred, day number: 3, weight: 98 Name: Fred, day number: 4, weight: 97 Restoring saved state. Name: Fred, day number: 2, weight: 99
 

Mediator Pattern-1

The mediator pattern is a behavioral object design pattern. The mediator pattern centralizes communication between objects into a mediator object. This centralization is useful since it localizes in one place the interactions between objects, which can increase code maintainability, especially as the number of classes in an application increases. Since communication occurs with the mediator rather than directly with other objects, the mediator pattern results in a loose coupling of objects.
The classes that communicate with the mediator are known as Colleagues. The mediator implementation is known as the Concrete Mediator. The mediator can have an interface that spells out the communication with Colleages. Colleagues know their mediator, and the mediator knows its colleagues.
Now, let's look at an example of this pattern. We'll create a Mediator class (without implementing a mediator interface in this example). This mediator will mediate the communication between two buyers (a Swedish buyer and a French buyer), an American seller, and a currency converter.
The Mediator has references to the two buyers, the seller, and the converter. It has methods so that objects of these types can be registered. It also has a placeBid() method. This method takes a bid amount and a unit of currency as parameters. It converts this amount to a dollar amount via communication with the dollarConverter. It then asks the seller if the bid has been accepted, and it returns the answer.

Mediator.java

package com.cakes;

public class Mediator {

 Buyer swedishBuyer;
 Buyer frenchBuyer;
 AmericanSeller americanSeller;
 DollarConverter dollarConverter;

 public Mediator() {
 }

 public void registerSwedishBuyer(SwedishBuyer swedishBuyer) {
  this.swedishBuyer = swedishBuyer;
 }

 public void registerFrenchBuyer(FrenchBuyer frenchBuyer) {
  this.frenchBuyer = frenchBuyer;
 }

 public void registerAmericanSeller(AmericanSeller americanSeller) {
  this.americanSeller = americanSeller;
 }

 public void registerDollarConverter(DollarConverter dollarConverter) {
  this.dollarConverter = dollarConverter;
 }

 public boolean placeBid(float bid, String unitOfCurrency) {
  float dollarAmount = dollarConverter.convertCurrencyToDollars(bid, unitOfCurrency);
  return americanSeller.isBidAccepted(dollarAmount);
 }
}
Here is the Buyer class. The SwedishBuyer and FrenchBuyer classes are subclasses of Buyer. The buyer has a unit of currency as a field, and it also has a reference to the mediator. The Buyer class has a attemptToPurchase() method. This method submits a bid to the mediator's placeBid() method. It returns the mediator's response.

Buyer.java

package com.cakes;

public class Buyer {

 Mediator mediator;
 String unitOfCurrency;

 public Buyer(Mediator mediator, String unitOfCurrency) {
  this.mediator = mediator;
  this.unitOfCurrency = unitOfCurrency;
 }

 public boolean attemptToPurchase(float bid) {
  System.out.println("Buyer attempting a bid of " + bid + " " + unitOfCurrency);
  return mediator.placeBid(bid, unitOfCurrency);
 }
}
The SwedishBuyer class is a subclass of Buyer. In the constructor, we set the unitOfCurrency to be "krona". We also register the SwedishBuyer with the mediator so that the mediator knows about the SwedishBuyer object.

SwedishBuyer.java

package com.cakes;

public class SwedishBuyer extends Buyer {

 public SwedishBuyer(Mediator mediator) {
  super(mediator, "krona");
  this.mediator.registerSwedishBuyer(this);
 }
}
The FrenchBuyer class is similar to the SwedishBuyer class, except the unitOfCurrency is "euro", and it registers with the mediator as the FrenchBuyer.

FrenchBuyer.java

package com.cakes;

public class FrenchBuyer extends Buyer {

 public FrenchBuyer(Mediator mediator) {
  super(mediator, "euro");
  this.mediator.registerFrenchBuyer(this);
 }
}

In the constructor of the AmericanSeller class, the class gets a reference to the mediator and the priceInDollars gets set. This is the price of some good being sold. The seller registers with the mediator as the AmericanSeller. The seller's isBidAccepted() method takes a bid (in dollars). If the bid is over the price (in dollars), the bid is accepted and true is returned. Otherwise, false is returned.

AmericanSeller.java

package com.cakes;

public class AmericanSeller {

 Mediator mediator;
 float priceInDollars;

 public AmericanSeller(Mediator mediator, float priceInDollars) {
  this.mediator = mediator;
  this.priceInDollars = priceInDollars;
  this.mediator.registerAmericanSeller(this);
 }

 public boolean isBidAccepted(float bidInDollars) {
  if (bidInDollars >= priceInDollars) {
   System.out.println("Seller accepts the bid of " + bidInDollars + " dollars\n");
   return true;
  } else {
   System.out.println("Seller rejects the bid of " + bidInDollars + " dollars\n");
   return false;
  }
 }

}
The DollarConverter class is another colleague class. When created, it gets a reference to the mediator and registers itself with the mediator as the DollarConverter. This class has methods to convert amounts in euros and kronor to dollars.

DollarConverter.java

package com.cakes;

public class DollarConverter {

 Mediator mediator;

 public static final float DOLLAR_UNIT = 1.0f;
 public static final float EURO_UNIT = 0.7f;
 public static final float KRONA_UNIT = 8.0f;

 public DollarConverter(Mediator mediator) {
  this.mediator = mediator;
  mediator.registerDollarConverter(this);
 }

 private float convertEurosToDollars(float euros) {
  float dollars = euros * (DOLLAR_UNIT / EURO_UNIT);
  System.out.println("Converting " + euros + " euros to " + dollars + " dollars");
  return dollars;
 }

 private float convertKronorToDollars(float kronor) {
  float dollars = kronor * (DOLLAR_UNIT / KRONA_UNIT);
  System.out.println("Converting " + kronor + " kronor to " + dollars + " dollars");
  return dollars;
 }

 public float convertCurrencyToDollars(float amount, String unitOfCurrency) {
  if ("krona".equalsIgnoreCase(unitOfCurrency)) {
   return convertKronorToDollars(amount);
  } else {
   return convertEurosToDollars(amount);
  }
 }
}
The Demo class demonstrates our mediator pattern. It creates a SwedishBuyer object and a FrenchBuyer object. It creates an AmericanSeller object with a selling price set to 10 dollars. It then creates a DollarConverter. All of these objects register themselves with the mediator in their constructors. The Swedish buyer starts with a bid of 55 kronor and keeps bidding up in increments of 15 kronor until the bid is accepted. The French buyer starts bidding at 3 euros and keeps bidding in increments of 1.50 euros until the bid is accepted.

Demo.java

package com.cakes;

public class Demo {

 public static void main(String[] args) {

  Mediator mediator = new Mediator();

  Buyer swedishBuyer = new SwedishBuyer(mediator);
  Buyer frenchBuyer = new FrenchBuyer(mediator);
  float sellingPriceInDollars = 10.0f;
  AmericanSeller americanSeller = new AmericanSeller(mediator, sellingPriceInDollars);
  DollarConverter dollarConverter = new DollarConverter(mediator);

  float swedishBidInKronor = 55.0f;
  while (!swedishBuyer.attemptToPurchase(swedishBidInKronor)) {
   swedishBidInKronor += 15.0f;
  }

  float frenchBidInEuros = 3.0f;
  while (!frenchBuyer.attemptToPurchase(frenchBidInEuros)) {
   frenchBidInEuros += 1.5f;
  }

 }

}
The console output of the execution of Demo is shown here.

Console Output

Buyer attempting a bid of 55.0 krona
Converting 55.0 kronor to 6.875 dollars
Seller rejects the bid of 6.875 dollars

Buyer attempting a bid of 70.0 krona
Converting 70.0 kronor to 8.75 dollars
Seller rejects the bid of 8.75 dollars

Buyer attempting a bid of 85.0 krona
Converting 85.0 kronor to 10.625 dollars
Seller accepts the bid of 10.625 dollars

Buyer attempting a bid of 3.0 euro
Converting 3.0 euros to 4.285714 dollars
Seller rejects the bid of 4.285714 dollars

Buyer attempting a bid of 4.5 euro
Converting 4.5 euros to 6.4285717 dollars
Seller rejects the bid of 6.4285717 dollars

Buyer attempting a bid of 6.0 euro
Converting 6.0 euros to 8.571428 dollars
Seller rejects the bid of 8.571428 dollars

Buyer attempting a bid of 7.5 euro
Converting 7.5 euros to 10.714286 dollars
Seller accepts the bid of 10.714286 dollars
In this example of the mediator pattern, notice that all communication between our objects (buyers, seller, and converter) occurs via the mediator. The mediator pattern helps reduce the number of object references needed (via composition) as classes proliferate in a project as a project grows.

Monday, May 3, 2010

Mediator Pattern

With the mediator pattern communication between objects is encapsulated with a mediator object. Objects no longer communicate directly with each other, but instead communicate through the mediator. This reduces the dependencies between communicating objects, thereby lowering the coupling.
Mediator Pattern

Intent


  • Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
  • Design an intermediary to decouple many peers.
  • Promote the many-to-many relationships between interacting peers to “full object status”.

Problem


We want to design reusable components, but dependencies between the potentially reusable pieces demonstrates the “spaghetti code” phenomenon (trying to scoop a single serving results in an “all or nothing clump”).

Discussion


In Unix, permission to access system resources is managed at three levels of granularity: world, group, and owner. A group is a collection of users intended to model some functional affiliation. Each user on the system can be a member of one or more groups, and each group can have zero or more users assigned to it. Next figure shows three users that are assigned to all three groups.
Mediator example

If we were to model this in software, we could decide to have User objects coupled to Group objects, and Group objects coupled to User objects. Then when changes occur, both classes and all their instances would be affected.

An alternate approach would be to introduce “an additional level of indirection” - take the mapping of users to groups and groups to users, and make it an abstraction unto itself. This offers several advantages: Users and Groups are decoupled from one another, many mappings can easily be maintained and manipulated simultaneously, and the mapping abstraction can be extended in the future by defining derived classes.
Mediator example

Partitioning a system into many objects generally enhances reusability, but proliferating interconnections between those objects tend to reduce it again. The mediator object: encapsulates all interconnections, acts as the hub of communication, is responsible for controlling and coordinating the interactions of its clients, and promotes loose coupling by keeping objects from referring to each other explicitly.

The Mediator pattern promotes a “many-to-many relationship network” to “full object status”. Modelling the inter-relationships with an object enhances encapsulation, and allows the behavior of those inter-relationships to be modified or extended through subclassing.

An example where Mediator is useful is the design of a user and group capability in an operating system. A group can have zero or more users, and, a user can be a member of zero or more groups. The Mediator pattern provides a flexible and non-invasive way to associate and manage users and groups.

Structure

Mediator scheme


Colleagues (or peers) are not coupled to one another. Each talks to the Mediator, which in turn knows and conducts the orchestration of the others. The “many to many” mapping between colleagues that would otherwise exist, has been “promoted to full object status”. This new abstraction provides a locus of indirection where additional leverage can be hosted.

Mediator scheme

Example


The Mediator defines an object that controls how a set of objects interact. Loose coupling between colleague objects is achieved by having colleagues communicate with the Mediator, rather than with each other. The control tower at a controlled airport demonstrates this pattern very well. The pilots of the planes approaching or departing the terminal area communicate with the tower rather than explicitly communicating with one another. The constraints on who can take off or land are enforced by the tower. It is important to note that the tower does not control the whole flight. It exists only to enforce constraints in the terminal area.
Mediator example

Check list


  1. Identify a collection of interacting objects that would benefit from mutual decoupling.
  2. Encapsulate those interactions in the abstraction of a new class.
  3. Create an instance of that new class and rework all “peer” objects to interact with the Mediator only.
  4. Balance the principle of decoupling with the principle of distributing responsibility evenly.
  5. Be careful not to create a “controller” or “god” object.

Rules of thumb


  • Chain of Responsibility, Command, Mediator, and Observer, address how you can decouple senders and receivers, but with different trade-offs. Chain of Responsibility passes a sender request along a chain of potential receivers. Command normally specifies a sender-receiver connection with a subclass. Mediator has senders and receivers reference each other indirectly. Observer defines a very decoupled interface that allows for multiple receivers to be configured at run-time.
  • Mediator and Observer are competing patterns. The difference between them is that Observer distributes communication by introducing “observer” and “subject” objects, whereas a Mediator object encapsulates the communication between other objects. We’ve found it easier to make reusable Observers and Subjects than to make reusable Mediators.
  • On the other hand, Mediator can leverage Observer for dynamically registering colleagues and communicating with them.
  • Mediator is similar to Facade in that it abstracts functionality of existing classes. Mediator abstracts/centralizes arbitrary communication between colleague objects, it routinely “adds value”, and it is known/referenced by the colleague objects (i.e. it defines a multidirectional protocol). In contrast, Facade defines a simpler interface to a subsystem, it doesn’t add new functionality, and it is not known by the subsystem classes (i.e. it defines a unidirectional protocol where it makes requests of the subsystem classes but not vice versa).

Iterator Pattern


Definition

Provide a way to move through a list of collection or aggregated objects without knowing its internal representations.

Where to use & benefits

  • Use a standard interface to represent data objects.
  • Use s standard iterator built in each standard collection, like List, Sort, or Map.
  • Need to distinguish variations in the traversal of an aggregate.
  • Similar to Enumeration class, but more effective.
  • Need to filter out some info from an aggregated collection.

Example

Employee is an interface, Manager, PieceWorker, HourlyWorker and CommissionWorker are implementation classes of interface Employee. EmployeeTest class will create a list and use a built-in iterator of ArrayList class to traverse the members of the list.
import java.util.*;
interface Employee {   
    public abstract double earnings();
}
class Manager implements Employee {
    private double weeklySalary;
    private String name;
    public Manager(String name, double s) {
        this.name = name;
        setWeeklySalary(s);
    }
    
    void setWeeklySalary(double s) {
        if (s > 0) {
          weeklySalary = s;
        } else
          weeklySalary = 0;
    }
    
    public double earnings() {
        return weeklySalary;
    }
    public String getName() {
     return name;
 }
    public String toString() {
        return "Manager: " + getName();
    }
}

class PieceWorker implements Employee {
    private double wagePerPiece;
    private int quantity;
    private String name;
    public PieceWorker(String name, double w, int q) {
        this.name = name;
        setWagePerPiece(w);
        setQuantity(q);
    }
    
    void setWagePerPiece(double w) {
        if (w > 0) 
          wagePerPiece = w;
        else
          wagePerPiece = 0;
    }
    
    void setQuantity(int q) {
        if ( q > 0)
           quantity = q;
        else
           quantity = 0;
    }
    public String getName() {
     return name;
 }    
    public double earnings() {
        return quantity * wagePerPiece;
    }
    
    public String toString() {
        return "Piece worker: " + getName();
    }
}

class HourlyWorker implements Employee {
    private double hourlyWage;
    private double hours;
    private String name;
    public HourlyWorker(String name, double w, double h) {
        this.name = name;
        setHourlyWage(w);
        setHours(h);
    }
    
    void setHourlyWage(double w) {
        if (w > 0)
            hourlyWage = w;
        else
            hourlyWage = 0;
    }
    
    void setHours(double h) {
        if ( 0 <= h && h < 168)
            hours = h;
        else
            hours = 0;
    }
    public String getName() {
     return name;
 }    
    public double earnings() {
        return hourlyWage * hours;
    }
    public String toString() {
        return "Hourly worker: " + getName();
    }
}

class CommissionWorker implements Employee {
    private double salary;
    private double commission;
    private double totalSales;
    private String name;
    public CommissionWorker(String name, 
            double salary, double commission, double totalSales) {  
        this.name = name;
        setSalary(salary);
        setCommission(commission);
        setTotalSales(totalSales);
    }
    void setSalary(double s) {
        if( s > 0)
            salary = s;
        else
            salary = 0;
    }  
    void setCommission(double c) {
        if ( c > 0)
            commission = c;
        else
            commission = 0;
    }
    void setTotalSales(double ts) {
        if (ts > 0 )
            totalSales = ts;
        else
            totalSales = 0;
    }
    public String getName() {
     return name;
 }
    public double earnings() {
        return salary + commission/100*totalSales;
    }  
    public String toString() {
        return "Commission worker:"
            + getName();
    }
}

class EmployeeTest {
    public static void main(String[] args) {
        java.util.List list = new ArrayList();
        list.add(new Manager("Bill", 800.00));
        list.add(new CommissionWorker("Newt", 400.0, 3.75, 159.99));
        list.add(new PieceWorker("Al", 2.5, 200));
        list.add(new HourlyWorker("Babara", 13.75, 40));
        list.add(new Manager("Peter", 1200.00));
        list.add(new CommissionWorker("Margret", 600.0,5.5, 200.25));
        list.add(new PieceWorker("Mark", 4.5, 333));
        list.add(new HourlyWorker("William", 31.25, 50));
    
  System.out.println("Use built-in iterator:");
  Iterator iterator = list.iterator();
  while(iterator.hasNext()) {
      Employee em = (Employee)iterator.next();
      System.out.print(em + " earns $");
   System.out.println(em.earnings());
  }
 }
}
%java EmployeeTest
Use built-in iterator:
Manager: Bill earns $800.0
Commission worker:Newt earns $405.999625
Piece worker: Al earns $500.0
Hourly worker: Babara earns $550.0
Manager: Peter earns $1200.0
Commission worker:Margret earns $611.01375
Piece worker: Mark earns $1498.5
Hourly worker: William earns $1562.5
The above example also shows a dynamic binding feature which is popular in Object-Oriented realm.
If you want to pick up a specific object from the aggregated list, you may use the following code.
while(iterator.hasNext()) {
 Employee em = (Employee)iterator.next();
 if (em instanceof Manager) {
    System.out.print(em + " earns $");
    System.out.println(em.earnings());
 }
}
The above list can also be replaced by an array and achieve the same result.

Interpreter Pattern

The Interpreter Pattern is a design pattern that defines a grammatical representation for a language along with an interpreter to interpret sentences in the language. The best example of an interpreted language is Java itself, which converts the English-written code to a byte code format, so that all the operating systems can understand it.
The UML class diagram of Interpreter design pattern can be shown as:

UML Class Diagram


In the given diagram, An abstract base class specifies the method interpret(). Each concrete subclass implements interpret() by accepting (as an argument) the current state of the language stream, and adding its contribution to the problem solving process. To make this thing clear, let’s take an example that can take the Sa, Re, Ga, Ma etc and produce the sounds for the frequencies. The “musical notes” is an Interpreted Language. The musicians read the notes, interpret them according to “Sa, Re, Ga, Ma…” or “Do, Re, Me… “, etc. For Sa, the frequency is 256 Hz, similarly, for Re, it is 288Hz and for Ga, it is 320 Hz and so on. In this case, we need these values set somewhere, so that when the system encounters any one of these messages, the related frequency can be sent to the instrument for playing the frequency. We can have it at one of the two places, one is a constants file, “token=value” and the other one being in a properties file. The properties file can give us more flexibility to change it later if required. This is how a properties file will look like: MusicalNotes.properties Sa=256
Re=288
Ga=320
Ma=352 . . . . .
After that we make a class NotesInterpreter.java to take an input from the key pressed by user and set those value as a global value. Then we make a method getFrequency for getting the frequency for the note input by the user e.g. if user enter Re, it will return 288.
NotesInterpreter.java

package bahavioral.interpreter; public class NotesInterpreter {

Private Note note;

public void getNoteFromKeys(Note note) {
Frequency freq = getFrequency(note);
sendNote(freq);
}
private Frequency getFrequency(Note note) {
return freq;
}
private void sendNote(Frequency freq) {
NotesProducer producer = new NotesProducer(); producer.playSound(freq);
}
}
Here we need to make another class in which the method produces the sound wave of the frequency it gets.

NotesProducer.java
package bahavioral.interpreter;
public class NotesProducer {
Private Frequency freq;
public NotesProducer() {
this.freq = freq;
}
public void playSound(Frequency freq) {
}
}
 The above example is the simplest way to understand the concept of interpreter pattern and know how it works. In case of Interpreter pattern we need to check for grammatical mistakes, which makes it very complex. Also,
care should be taken to make the interpreter as flexible as possible, so that the implementation can be changed at later stages without having tight coupling.

Command Pattern

Definition

Streamlize objects by providing an interface to encapsulate a request and make the interface implemented by subclasses in order to parameterize the clients.

Where to use & benefits

  • One action can be represented in many ways, like drop-down menu, buttons and popup menu.
  • Need a callback function, i.e., register it somewhere to be called later.
  • Specify and execute the request at different time
  • Need to undo an action by storing its states for later retrieving.
  • Decouple the object with its trigger
  • Easily to be extensible by not touching the old structure.

Example

The simple example of Command pattern is to design a Command interface and with an execute method like this:
public interface Command {
    public void execute();
}
Then, design multiple implementation classes and see how powerful the execute() method has been called dynamically.
In order to take advantage of Java built-in interfaces, we will design a window with a drop down menu, button commands and popup menu with command pattern.
As we know, JButton, JMenuItem and JPopupMenu have constructors accept Action type variable. Action interface extends ActionListener, which has the following hierarchy.
public interface EventLister {
   ...
}

public interface ActionListener extends EventListener {
   ...
}

public interface Action extends ActionListener {
   ...
}
There is an abstract class called AbstractAction which implements Action interface. It has the following design.
public abstract class AbstractAction extends Object
                   implements Action, Cloneable, Serializable
We will create several command classes to subclass the AbstractAction class and pass them to the constructors of JButton, JMenuItem and JPopupMenu classes. There is a request method called actionPerformed(), every command classes must implement it in order to make it work. To show the concept, we just design two actions: submit and exit. You may expand such design to your need in your future project.
Such action can be attached to any component, AWT or Swing. The caption, and Icon have been designed as well as tooltips.
class ExitAction extends AbstractAction {
   private Component target;
   public ExitAction(String name, Icon icon, Component t){
       putValue(Action.NAME, name);
       putValue(Action.SMALL_ICON, icon);
       putValue(Action.SHORT_DESCRIPTION, name + " the program");
       target = t;
   }    
   public void actionPerformed(ActionEvent evt) {
       int answer = JOptionPane.showConfirmDialog(target, "Are you sure you want to exit? ", "Confirmation",
                           JOptionPane.YES_NO_OPTION);
       if ( answer == JOptionPane.YES_OPTION) {                   
           System.exit(0);
       }       
   }
} 
Similar to the above exit action, the submit action is as follows:
class SubmitAction extends AbstractAction {
   private Component target;
   public SubmitAction(String name, Icon icon, Component t){
       putValue(Action.NAME, name);
       putValue(Action.SMALL_ICON, icon);
       putValue(Action.SHORT_DESCRIPTION, name + " the program");
       target = t;
   }    
   public void actionPerformed(ActionEvent evt) {
       JOptionPane.showMessageDialog(target, "submit action clicked ");
   }
} 
You can modify the program to add more commands in. These command classes are decoupled from any program. It is very good for maintenance.
The whole workable program is as follows. You can run it to see the powerful command design pattern.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

class ExitAction extends AbstractAction {
   private Component target;
   public ExitAction(String name, Icon icon, Component t){
       putValue(Action.NAME, name);
       putValue(Action.SMALL_ICON, icon);
       putValue(Action.SHORT_DESCRIPTION, name + " the program");
       target = t;
   }    
   public void actionPerformed(ActionEvent evt) {
       int answer = JOptionPane.showConfirmDialog(target, "Are you sure you want to exit? ", "Confirmation",
                           JOptionPane.YES_NO_OPTION);
       if ( answer == JOptionPane.YES_OPTION) {                   
           System.exit(0);
       }       
   }
} 

class SubmitAction extends AbstractAction {
   private Component target;
   public SubmitAction(String name, Icon icon, Component t){
       putValue(Action.NAME, name);
       putValue(Action.SMALL_ICON, icon);
       putValue(Action.SHORT_DESCRIPTION, name + " the program");
       target = t;
   }    
   public void actionPerformed(ActionEvent evt) {
       JOptionPane.showMessageDialog(target, "submit action clicked ");
   }
} 

class Test extends JFrame{
    Test() {
        Action ea = new ExitAction("Exit", null, this);
        Action sa = new SubmitAction("Submit", null, this);
        
        JMenuBar jbr = new JMenuBar();
        JMenu dropmenu= new JMenu("File");    
        JMenuItem submitmenu = new JMenuItem(sa);
        JMenuItem exitmenu = new JMenuItem(ea);
        dropmenu.add(submitmenu);
        dropmenu.add(exitmenu);
        jbr.add(dropmenu);
        setJMenuBar(jbr);
        
       final JPopupMenu pop = new JPopupMenu("PopMenu");
       pop.add(sa);
       pop.add(ea);
       addMouseListener(new MouseAdapter() {
           public void mousePressed(MouseEvent e) {
               showPopup(e);
           }
                  
           public void mouseReleased(MouseEvent e) {
               showPopup(e);
           }
                  
            private void showPopup(MouseEvent e) {
                if (e.isPopupTrigger()) {
                     pop.show(e.getComponent(),
                               e.getX(), e.getY());
                }
            }
         
        });
        JPanel jp = new JPanel();
        JButton subbtn = new JButton(sa);
        JButton exitbtn = new JButton(ea);
        jp.add(subbtn);
        jp.add(exitbtn);
        
        Container con = getContentPane();
        con.add(jp, "South");
        
        setTitle("Command pattern example");
        setSize(400,200);
        setVisible(true);
   }

   public static void main(String[] args) {
        new Test();    
   }
}
java Test

A windows pops up. 
Pay attention to the action buttons. The instances can be parameterized to JButton, JMenuItem and JPopupMenu constructors. The powerful action design (Java built-in Action interface) makes objects like ExitAction, SubmitAction be used everywhere. Design once, use everywhere.

Sunday, May 2, 2010

Chain of Responsibility Pattern


Definition

Let more than one object handle a request without their knowing each other. Pass the request to chained objects until it has been handled.

Where to use & benefits

  • One request should be handled by more than one object.
  • Don't know which object should handle a request, probably more than one object will handle it automatically.
  • Reduce coupling.
  • Flexible in handling a request.

Example

The Java Servlet filter framework is an example of chain of resposibility design. Note that the chain.doFilter() is the method that should be called to make the chain roll. If the subclass missed it, the whole chain would be stopped or blocked.
Java exception handling is another example of chain of responsibility design. When an error occurs, the exception call will look for a handling class. If there is no handler, the super Exception class will be called to throw the exception. Otherwise, the handler class will handle it.
Here comes a simple example, just to show how chain of responsibility works. Whenever you spend company's money, you need get approval from your boss, or your boss's boss. Let's say, the leadership chain is:
Manager-->Director-->Vice President-->President
The following is a command line program to check who is responsible to approve your expenditure.
import java.io.*;
abstract class PurchasePower {

    protected final double base = 500;
    protected PurchasePower successor;

    public void setSuccessor(PurchasePower successor){
        this.successor = successor;
    }

    abstract public void processRequest(PurchaseRequest request);
}

class Manager extends PurchasePower {
    private final double ALLOWABLE = 10 * base;

    public void processRequest(PurchaseRequest request ) {
        if( request.getAmount() < ALLOWABLE )
            System.out.println("Manager will approve $"+ request.getAmount());
        else
           if( successor != null)
               successor.processRequest(request);
  }
}

class Director extends PurchasePower {
    private final double ALLOWABLE = 20 * base;

    public void processRequest(PurchaseRequest request ) {
        if( request.getAmount() < ALLOWABLE )
            System.out.println("Director will approve $"+ request.getAmount());
        else
           if( successor != null)
               successor.processRequest(request);
  }
}

class VicePresident extends PurchasePower {
    private final double ALLOWABLE = 40 * base;

    public void processRequest(PurchaseRequest request) {
        if( request.getAmount() < ALLOWABLE )
            System.out.println("Vice President will approve $" + request.getAmount());
        else
        if( successor != null )
            successor.processRequest(request);
  }
}

class President extends PurchasePower {
    private final double ALLOWABLE = 60 * base;
   
    public void processRequest(PurchaseRequest request){
        if( request.getAmount() < ALLOWABLE )
            System.out.println("President will approve $" + request.getAmount());
        else
            System.out.println( "Your request for $" + request.getAmount() + " needs a board meeting!");
    }
}

class PurchaseRequest {
  
    private int number;
    private double amount;
    private String purpose;

    public PurchaseRequest(int number, double amount, String purpose){
        this.number = number;
        this.amount = amount;
        this.purpose = purpose;
    }

    public double getAmount() {
        return amount;
    }
    public void setAmount(double amt){
        amount = amt;
    }
    
    public String getPurpose() {
        return purpose;
    }
    public void setPurpose(String reason) {
        purpose = reason;
    }

    public int getNumber(){
        return number;
    }
    public void setNumber(int num) {
        number = num;
     }   
}

class CheckAuthority {
    public static void main(String[] args) throws Exception{
        Manager manager = new Manager();
        Director director = new Director();
        VicePresident vp = new VicePresident();
        President president = new President();
        manager.setSuccessor(director);
        director.setSuccessor(vp);
        vp.setSuccessor(president);
        
        //enter ctrl+c to kill.
        while (true) {
            System.out.println("Enter the amount to check who should approve your expenditure.");
            System.out.print(">");
            double d = Double.parseDouble(new BufferedReader(new InputStreamReader(System.in)).readLine());
            manager.processRequest(new PurchaseRequest(0, d, "General"));
        }

  }
}
C:\Command Prompt

C:\> javac CheckAuthority.java
C:\> java CheckAuthority

Enter the amount to check who should approve your expenditure.
>500
Manager will approve $500.0
Enter the amount to check who should approve your expenditure.
>5000
Director will approve $5000.0
Enter the amount to check who should approve your expenditure.
>11000
Vice President will approve $11000.0
Enter the amount to check who should approve your expenditure.
>30000
Your request for $30000.0 needs a board meeting!
Enter the amount to check who should approve your expenditure.
>20000
President will approve $20000.0
Enter the amount to check who should approve your expenditure.
>
C:\>
You may redo it using interface instead of abstract class.
The composite pattern is often used with chain of responsibility. That means a class may contain the related class that may handle the request.

Friday, April 30, 2010

Behavioral patterns

Behavioral patterns are those which are concerned with interactions between the objects. The interactions between the objects should be such that they are talking to each other and still are loosely coupled. The loose coupling is the key to n-tier architectures. In this, the implementation and the client should be loosely coupled in order to avoid hard-coding and dependencies.
The behavioral patterns are:
Patterns.
1. Chain Of Responsibility Pattern
2. Command Pattern
3. Interpreter Pattern
4. Iterator Pattern
5. Mediator Pattern
6. Momento Pattern
7. Observer Pattern
8. State Pattern

9. Strategy Pattern

10. Template Pattern

11. Visitor Pattern


I will describe each one of these in details

 

Proxy Pattern

Structural Patterns - Proxy Pattern
The proxy pattern is used when you need to represent a complex with a simpler one. If creation of object is expensive, its creation can be postponed till the very need arises and till then, a simple object can represent it. This simple object is called the “Proxy” for the complex object

The cases can be innumerable why we can use the proxy. Let’s take a scenario. Say, we want to attach an image with the email. Now, suppose this email has to be sent to 1 lakh consumers in a campaign. Attaching the image and sending along with the email will be a very heavy operation. What we can do instead is, send the image as a link to one of the sevlet. The place holder of the image will be sent. Once the email reaches the consumer, the image place holder will call the servlet and load the image at run time straight from the server.

Let’s try and understand this pattern with the help of a non-software example as we have tried to do throughout this article.

Let’ say we need to withdraw money to make some purchase. The way we will do it is, go to an ATM and get the money, or purchase straight with a cheque. In old days when ATMs and cheques were not available, what used to be the way??? Well, get your passbook, go to bank, get withdrawal form there, stand in a queue and withdraw money. Then go to the shop where you want to make the purchase. In this way, we can say that ATM or cheque in modern times act as proxies to the Bank.

Let’s look at the code now.

Bank will define the entire method described above. There are references of classes like You (as the person who wants to withdraw money), also Account, as persons account. These are dummy classes and can be considered of fulfilling the responsibilities as described.


Bank.java

package structural.proxy;
/**
* Bank.java
* The class acts as the main object for which
* the proxy has to be created. As described, going
* to bank for withdrawal is very costly time wise.
*/
public class Bank {
  private int numberInQueue;
/**
* Method getMoneyForPurchase
* This method is responsible for the entire banking
* operation described in the write-up
*/
public double getMoneyForPurchase(double amountNeeded) {

// get object for person
You you = new You("Prashant");
// get obj for account
Account account = new Account();
// get person's account number
String accountNumber = you.getAccountNumber();
// passbook got.
boolean gotPassbook = you.getPassbook();
// get number in queue
int number = getNumberInQueue();

// the number will decrease every few mins
while (number != 0) {
number--;
}

// now when the number = 0, check if balance is sufficient
boolean isBalanceSufficient = account.checkBalance(accountNumber, amountNeeded);

if(isBalanceSufficient)
return amountNeeded;
else
return 0;
}

/**
* returns the number in the queue
*/
private int getNumberInQueue() {
return numberInQueue;
}

}// End of class
Also, the second class is ATMProxy. This also defines the way the transaction can be handled for withdrawal of money.

ATMProxy.java

package structural.proxy;

public class ATMProxy {

  /**
* Method getMoneyForPurchase
* This method is responsible for the entire banking
* operation described in the write-up
*/
public double getMoneyForPurchase(double amountNeeded) {

// get obj of You to get card
You you = new You("Prashant");
// get obj for account
Account account = new Account();

boolean isBalanceAvailable = false;
// if card there, go ahead
if(you.getCard()) {
isBalanceAvailable = account.checkBalance(you.getAccountNumber(), amountNeeded);
}

if(isBalanceAvailable)
return amountNeeded;
else
return 0;
}
}// End of class
Here, we can also create another proxy called ChequeProxy. I am not creating it here as the message I wanted to send across has been conveyed with the help of one proxy only. We can see here that creation of object of Bank is very costly, effort and time wise, and so, we can as well use a proxy called ATM to get the result. ATM can internally communicate with the Bank object. So, ATM here is also acting like a façade.
This might and might not happen. It can happen that we at a later stage have to create the same heavy object. We just want to postpone the creation of object to the last minute so that the application is not loaded by resources utilized for creating the object.