Saturday, March 13, 2010

Observer design pattern (Publisher-Subscriber)

The use of observer design pattern is ubiquitous in Java. We just have to consider Swing classes, GUI frameworks, RMI, JavaBeans etc to note its pervasive nature. Whenever a component registers for an action event, it is using the Observer pattern. The straightforward principle is that whenever multiple parties (observers) are interested in the changes of state of an object (subject/observable) then they subscribe for the notification of changes. The observable object monitors its state and on observing relevant change in its state, it notifies all the interested parties through a common update() interface. The subject provides methods for the subscription and un-subscription. Obviously, the subject can either push all the changes to the observers or allow the observers to pull the changes on notification through provides API. The key is that the subject and the observers are loosely coupled, as the subject has no knowledge of the observers.

Our sample program clearly illustrate the principle.

package raj;

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

public class TestObserver {

public static void main(String[] arg) {
// create the subject we are interested in subscribing
Subject subject = new Subject();
// create the subscriber for the subject
Bar interestedObserver = new Bar();
// add subscribers
subject.addObserver(new Foo());
subject.addObserver(new Bar());
subject.addObserver(interestedObserver);
// subject state changes; the observers notified
subject.stateChange();
// unsubscribe
subject.removeObserver(interestedObserver);
// check the unsubscribed party doesn't get further notification
subject.stateChange();
}
}

class Subject {

List observerList = new ArrayList();

public void addObserver(Observer o) {
observerList.add(o);
}

public void removeObserver(Observer o) {
int index = observerList.indexOf(o);
if (index >= 0) {
observerList.remove(index);
}
}

public void notifyObservers() {
for (Observer o : observerList) {
o.update("change");
}
}

public void stateChange() {
notifyObservers();
}
}

interface Observer {

public void update(String message);
}

class Foo implements Observer {

public void update(String message) {
System.out.println("Foo: " + message);
}
}

class Bar implements Observer {

public void update(String message) {
System.out.println("Bar: " + message);
}
}

We have opted for push technique in our example but it could be more appropriate to use pull as it allows the observer more flexibility in responding to the change.

Also it is worth noticing that Java provides its own implementation of Observer and Observable in the java.util package so the above sample could have been codes as:

import java.util.Observable;
import java.util.Observer;

public class JavaObserver extends Observable {
private String message;

public String getMessage() {
return message;
}

public void stateChange(String message) {
this.message = message;
setChanged(); // signifies state change
notifyObservers(message);
// the line below is for 'pull' as we pass the object so getMessage() can be invoked
// notifyObservers(this);
}

public static void main(String[] args) {
JavaObserver subject = new JavaObserver();
Baz bar = new Baz();
Baz baz = new Baz();
Baz foo = new Baz();
subject.addObserver(foo);
subject.addObserver(bar);
subject.addObserver(baz);
subject.stateChange("Change!");
}
}

class Baz implements Observer {
public void update(Observable o, Object message) {
System.out.println("Baz: " + message); // push
// the line below is for 'pull'
// System.out.println("Baz: " + ((JavaObserver) message).getMessage());

}
}

The key restriction of the Java built-in functionality is that we have to extend the Observable class so there is no way extending JavaObserver from any other class.







Model-View-Controller (MVC) pattern

The MVC architectural pattern is the bedrock of technologies like JavaServer Faces and is fundamental to implementing three-tier architecture. It clearly segregates the model in the business layer, view in the presentation layer and the controller, which handles all the inputs affecting the model. Obviously if the model is totally segregated then it becomes relatively easier to test the domain logic with automated tools. We can illustrate this decoupling of model and view through a simple calculator application which takes two numbers and applies the requested operator to provide the result.


package mvc;

import java.awt.event.ActionEvent;
import javax.swing.*;

public class MvcTest {

private static void buildUI() {
MvcModel model = new MvcModel();
MvcView view = new MvcView();
MvcControl control = new MvcControl("Result", view, model);
view.setControl(control);

JFrame frame = new JFrame("Test Calculator");
frame.getContentPane().add(view.getMainPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {
buildUI();
}
});
}
}

class MvcView {
// mainPanel holds all the GUI components

private JPanel mainPanel = new JPanel();
// two input fields and the result textfield
private JTextField firstOperand = new JTextField(10);
private JTextField operator = new JTextField(1);
private JTextField secondOperand = new JTextField(10);
private JTextField resultField = new JTextField(10);
private JButton addButton = new JButton();

public MvcView() {
resultField.setEditable(false);
operator.setText("+"); // default to add
mainPanel.add(firstOperand);
mainPanel.add(operator);
mainPanel.add(secondOperand);
mainPanel.add(new JLabel("="));
mainPanel.add(resultField);
mainPanel.add(addButton);
}

public void setControl(MvcControl control) {
addButton.setAction(control);
}

public JPanel getMainPanel() {
return mainPanel;
}

public String getFirstOperandText() {
return firstOperand.getText();
}

public String getSecondOperandText() {
return secondOperand.getText();
}

public String getOperatorText() {
return operator.getText();
}

public void setResultText(String text) {
resultField.setText(text);
}
}

class MvcControl extends AbstractAction {

private MvcModel model;
private MvcView view;

public MvcControl(String text, MvcView view, MvcModel model) {
super(text);
this.view = view;
this.model = model;
}

public void actionPerformed(ActionEvent e) {
view.setResultText(""); // clear the result
try {
double op1 = Double.parseDouble(view.getFirstOperandText());
double op2 = Double.parseDouble(view.getSecondOperandText());
char operator = view.getOperatorText().charAt(0);
if (operator == '+'
|| operator == '-'
|| operator == '*'
|| operator == 'x'
|| operator == 'X'
|| operator == '/'
|| operator == '%') {}
else throw new IllegalArgumentException();
double result = model.doOperation(op1, op2, operator); // use the model here
view.setResultText(String.valueOf(result));
} catch (NumberFormatException nfe) {
JOptionPane.showMessageDialog(view.getMainPanel(), "Only Numbers Allowed",
"Data Error", JOptionPane.ERROR_MESSAGE);
} catch (IllegalArgumentException nfe) {
JOptionPane.showMessageDialog(view.getMainPanel(), "The operator must be one of *, /, +, - or %",
"Data Error", JOptionPane.ERROR_MESSAGE);
}
}
}

class MvcModel {

public double doOperation(double op1, double op2, char operator) {
double result = 0;
switch (operator) {
case '+':
result = op1 + op2;
break;
case '-':
result = op1 - op2;
break;
case '*':
case 'x':
case 'X':
result = op1 * op2;
break;
case '/':
result = op1 / op2;
break;
case '%':
result = op1 % op2;
}
return result;
}
}

It is clear in our example that the view (MvcView) is the user interface which asks for two operands and the mathematical operation to apply on them. Model (MvcModel) is passed these inputs by the controller (MvcController) to get the calculation result. In our design the view has no knowledge of the model and the controller is an observer of the action performed on the 'result' button in the view. The controller uses its knowledge of the view to update the result. Thus a clear segregation of roles has been achieved. Obviously an application can have a number of these MVC triplets.






Friday, March 12, 2010

Factory design pattern

Let us give ourselves godlike powers and create a factory to produce animals. The basic structure for such a factory would look like:

package raj;

/**
* @author Rajeev
*/
public class AnimalFactory {
private String animalType;
AnimalFactory(String animalType) {
this.animalType = animalType;}

public Animal createAnimal() {
if (animalType.equals("Dog")) return new Dog();
else if (animalType.equals("Cat")) return new Cat();
else if (animalType.equals("Donkey")) return new Donkey();
else if (animalType.equals("Horse")) return new Horse();
else return new Animal();
}
}

class Animal {public String toString(){return "Animal";}}
class Dog extends Animal {public String toString(){return "Dog";}}
class Cat extends Animal {public String toString(){return "Cat";}}
class Donkey extends Animal {public String toString(){return "Donkey";}}
class Horse extends Animal {public String toString(){return "Horse";}}

It allows us to create an animal of a type which the factory has been geared to produce. We can test it with:

package raj;

/**
* @author Rajeev
*/
public class TestFactory {

public static void main(String[] arg) {
// create factories
AnimalFactory horseFactory = new AnimalFactory("Horse");
AnimalFactory dogFactory = new AnimalFactory("Dog");
AnimalFactory catFactory = new AnimalFactory("Cat");
AnimalFactory donkeyFactory = new AnimalFactory("Donkey");
AnimalFactory animalFactory = new AnimalFactory("");
// create horses
Animal animal = horseFactory.createAnimal();
Animal animal2 = horseFactory.createAnimal();
System.out.printf("We are type %s %s%n",animal,animal2);
// create dogs
animal = dogFactory.createAnimal();
animal2 = dogFactory.createAnimal();
System.out.printf("We are type %s %s%n",animal,animal2);
// create cats
animal = catFactory.createAnimal();
animal2 = catFactory.createAnimal();
System.out.printf("We are type %s %s%n",animal,animal2);
// create donkeys
animal = donkeyFactory.createAnimal();
animal2 = donkeyFactory.createAnimal();
System.out.printf("We are type %s %s%n",animal,animal2);
// create animals
animal = animalFactory.createAnimal();
animal2 = animalFactory.createAnimal();
System.out.printf("We are type %s %s%n",animal,animal2);

}
}

Now if we decide to produce 'sheep' in future or make a species extinct then all we have to do is to alter the Factory class to incorporate this new requirement at one central place. A demigod could be allocated a particular factory type now and he can happily go on churning objects of that particular species. This programming idiom is useful but not the Factory method pattern defined by GoF. Our current UML diagram is shown in Fig 1.


The GoF Factory method design pattern would alter the diagram to Fig 2.
With this variation, the TestFactory client is totally isolated from the realisation of the factory and its products (the concrete Animal). In this approach the client talks to the abstract interfaces which delegate the actual implementation to their subclasses. Our code changes accordingly to make this possible.

package raj;

public class TestFactoryFM {

public static void main(String[] arg) {
// create factory
AnimalFactoryIF horseFactory = new AnimalFactory("Horse");
// create horses
AnimalIF animal = horseFactory.createAnimal();
AnimalIF animal2 = horseFactory.createAnimal();
System.out.printf("We are type %s %s%n",animal,animal2);}
}

abstract class AnimalFactoryIF {abstract public AnimalIF createAnimal();}
class AnimalFactory extends AnimalFactoryIF {
private String animalType;
AnimalFactory(String animalType) {
this.animalType = animalType;}

public AnimalIF createAnimal() {
if (animalType.equals("Dog")) return new Dog();
else if (animalType.equals("Cat")) return new Cat();
else if (animalType.equals("Donkey")) return new Donkey();
else if (animalType.equals("Horse")) return new Horse();
else return new Animal();
}
}

abstract class AnimalIF { abstract public String toString();};
class Animal extends AnimalIF {public String toString(){return "Animal";}}
class Dog extends Animal {public String toString(){return "Dog";}}
class Cat extends Animal {public String toString(){return "Cat";}}
class Donkey extends Animal {public String toString(){return "Donkey";}}
class Horse extends Animal {public String toString(){return "Horse";}}

Hitherto, in our approach we have one-to-one relationship between the AnimalIF and its subclass and the FactoryIF and its subclass. However, the power of the approach becomes apparent if subclass our FactoryIF with another factory, SpecialFactory, which produces superior quality animals, SpecialAnimal, which are a subclass of the AnimalIF. The client is built to an interface and is totally unaware of the type of animal it is dealing with. Unsurprisingly, the Factory method design is used frequently in frameworks.

Compilation failures one should know in Java

Those of you who are preparing for SCJP are aware that nearly every question has 'compilation will fail' as an option. Here is a short random list of the compilation failures one should watch out for. No list of this nature can be comprehensive but it does include many useful hints.

while (false) {} // immediate error on the line
while (true) {}; // immediate error on the line following the loop
but while (true) {break;}
System.out.println(""); will compile.

throw new RuntimeException; // the line following is unreachable

go(1) when go(short i); // cannot down cast int to short have to say go((short) 1)

assert (): go(); where void go() // need a string and cannot have void

final X f = new X(); and then f=null; // cannot assign anything to reference
final int x=5; then x++ // especially with interface constants

importing static from a different package whose access is defined as default

We can define unused variables. It is not a compilation failure but just like unused imports.

switch case has a non-compile time literal (ie it is not defined and initiated final on the same line. It is not good enough to declare it as final on one line and then initialize it on the next).

You can't change the return type of overridden method, if return is int in parent then can't return Integer or short in the child. The temptation because of covariant returns is that it may be possible. An overridden method can return the child of a class defined in the parent. However it is a compile error to return parent to a child return type. If expecting Number m() return Integer; is fine, and Integer m() return Integer; is fine but Integer m() return Number; will not compile.

Calling super or instance from static block. Always ensure that an object exists in main before invocation of methods.

Using join, sleep or wait without handling InterruptedException or throwing InterrupedException from run(). The latter breaches the contract of Runnable interface by throwing an unexpected checked exception.

Method with no return type will not compile

new myrunnable().start will not compile. Has to be new Thread(myrunnable).start

class X is not correct nor is class

import static with just the class name fails

There is no such thing as super.super to invoke parent's parent.

You cannot override a static method with a non-static or vice versa.

try {} System.out.println("Here"); catch () {} will fail. No statements between try and catch.

parse needs to catch ParseException

run() cannot throw InterruptedException // no checked exception can be thrown which interface didn't define

for(String s:aa) // declaration has to be within foreach and s should not have been declared before. However it is OK to have s being used in multiple foreach as each has just the local scope.

assert 1 > 2: go(); // will not compile if from within main or any static block if go() not static

inner classes cannot have static members so be wary of their definitions.

import static java.lang.Integer.MAX_VALUE; then import static java.lang.Short.MAX_VALUE; as MAX_VALUE already defined.

declaring enum in a method fails

void doMore() {throw new IOException) fails becuase checked exception must say doMaore() throws IOException

If we catch Exception() then compiler won't allow any child of it to follow it. The order matters.

Putting long in switch expression, it can only be int or thing which can convert to in like char, byte, short

trying to use uninitialized local variable in a method or trying to prefix them with access modifier. Only valid modifier within method is final. Watch out for private int i = 5 in a method.

enum outside class can not be marked static, final, abstract, private or protected. Within the class it can be marked static, private or protected but not abstract or final.
myenum xx= new myenum(); won't compile. Enums are just initialised.

Trying to cast char into a String. char is a primitive and String is an object so S = c fails.

Instance variables cannot be marked strictfp, native, synchronized, abstract. final and transient are fine.

Not having a proper main() method is a runtime error, not a compiler error!

char c = -1; is illegal but char c = (char) -1 is OK. Char is unsigned integer literal with max value of 65535;

byte a = 3; byte b = 2; but byte c = a + b; will not compile as the result is an int. However byte c = 3 +5 is OK as within range and the compiler knows.

float f = 23.4; will not compile as 23.4 is a double.
A variable defined within the initialisation block is not visible to the program, ie {int j = 1;} j cannot be seen anywhere. Trying to use it later will not compile.

int i = 5; static {i = 7;} will not work as i is non-static.

You can't widen an Integer into a Long. The wrapper classes are different objects.

if (5 && 6) will not compile. The expression has to evaluate to boolean

if (x=6) is an illegal argument to if. It is just assigning. Can get away with this with boolean otherwise compile fails.

Integer i = new Integer(4); switch (i) is wrong if used as a case expression in switch statement.

continue statements must be inside a loop; otherwise, you’ll get a compiler error. break statements must be used inside either a loop or switch statement.

Labelled continue and break statements must be inside the loop that has the same label name; otherwise, the code will not compile.

Object test() { return (Double) 2.7;} works Object test() { return (Float) 2.7;} doesn't works 2.7 boxes to Double

Short n = new Short((short) 3); without the cast it fails. However it is ok to say Short s = 555; Integer i = 1 etc as long as they are within range.

More importantly it is fine to compare the incompatible wrapper types like Integer, Short etc with relational operators like greater than or greater than or equal to but not right to use ==. For relational comparisons of greater than, less than etc. it auto unboxes and doesn't complain.

boolean equals(Object o) {return true;} doesn't compile. hashCode(), toString() too are PUBLIC methods. As they are without public modifier they are improper override.

Watch out for missing semicolon in the definition of anonymous inner class.

The compiler will complain if you try to invoke any method on an anonymous inner class reference that is not in the superclass class definition.

Beware of sticking static in front of run() it will not compile as being improper override.

The public access modifier is the only one that allows code from outside a package to access methods in a package regardless of inheritance. If we are overriding a method in a subclass in a different package then the method must be public.

While using an interface from a different package, it must be declared public or we will not be able to use it. Just default package will not work.

Singleton design pattern

It is conceptually the simplest design pattern and many argue that it is actually an anti-pattern and continues to exist within computing courses because GoF specified it in their seminal work and it offers easy introduction to the subject of design patterns. Controversial it may well be but it has a useful purpose when we do genuinely need just one object of a class. Obviously the logger is the primary example.

The design is simple:

package raj;

class TestSingleton {
public static void main(String[] arg) {
Singleton s = Singleton.getInstance();
System.out.println(s.toString());
s.setVal(100);
Singleton s2 = Singleton.getInstance();
System.out.println(s2.toString());
System.out.println(s2.getVal());
}
}

public class Singleton {

private static Singleton singletonObj;

private Singleton() {
}
private int val = 0;

public int getVal() {
return val;
}

public void setVal(int val) {
this.val = val;
}

public static Singleton getInstance() {
if (singletonObj == null) {
singletonObj = new Singleton();
}
return singletonObj;
}
}

It relies on having a private constructor and public static interface to provide the object. We can make this design thread-safe by synchronizing the getInstance() method:

public static synchronized Singleton getInstance() {
if (singletonObj == null) {
singletonObj = new Singleton();
}
return singletonObj;
}

However, this approach would considerably slow down the access to the object as synchronization can be painfully slow and is only needed during the first create. To over come this we may eschew lazy instantiation of the object and change our Singleton class to the following to let the class loader take the responsibility for instantiation:

public class Singleton {

private static Singleton singletonOb = new Singleton();j;

private Singleton() {
}
private int val = 0;

public int getVal() {
return val;
}

public void setVal(int val) {
this.val = val;
}

public static Singleton getInstance() {
return singletonObj;
}
}

This is great! But if the objected created is a scarce resource and is never used then it obviously is wasteful. A thread-safe compromise solution would be to use double-checked locking:

public static Singleton getInstance() {
if (singletonObj == null) {
synchronized (Singleton.class) {
if (singletonObj == null) singletonObj = new Singleton();
}}
return singletonObj;
}

Now we take the synchronization hit just during the create but there is still a small overhead of an extra conditional check during every access. Also note that we cannot use synchronized(this) as we are locking from within a static context so need the class literal Singleton.class.

Thursday, March 11, 2010

Decorator design pattern

When a computer manufacturer like Dell is confronted with a scenario of supplying basic computer with various add-ons, how does it provide the correct description for the configuration and its correct price? One option would be to create a Computer class and then subclass it with each variant like ComputerPlusWindows, ComputerPlusWindowsPlusExtraMemory etc. We can already see the classes proliferating and the nightmare gets worse when the price of a component changes as it would need to be reflected in each configuration using the changed price. Here the utility of Decorator design pattern becomes evident as we can can create wrapper classes for the variants which HAS-A computer. The trick is to create an abstract decorator for our original Computer class and let all the variant classes extend this decorator while wrapping themselves around the Computer class. In our example below, we have taken a basic Computer with price and description and created just two variants of Windows7Computer and ExtraMemoryComputer to correctly reflect the name of the add-on and the price with the add-on.

package raj;

/**
* @author Rajeev
*/
public class DecoratorTest {
public static void main(String[] arg) {
Computer computer = new Computer();
// put windows 7 wrapper
computer = new Windows7Computer(computer);
System.out.println(computer.getDescription());
System.out.println("Cost "+ computer.getPrice());
/* Basic computer + Winodws 7
Cost 230.75
*/
// put extra memory wrapper
computer = new ExtraMemoryComputer(computer);
System.out.println(computer.getDescription());
System.out.println("Cost "+ computer.getPrice());
/* Basic computer + Winodws 7 + 2G memory
Cost 281.5
*/
// put more extra memory
computer = new ExtraMemoryComputer(computer);
System.out.println(computer.getDescription());
System.out.println("Cost "+ computer.getPrice());
/* Basic computer + Winodws 7 + 2G memory + 2G memory
Cost 332.25
*/
}
}

class Computer {

private String description = "Basic computer";
private double price = 200.50;

public String getDescription() {
return description;
}

public double getPrice() {
return price;
}
}

abstract class ComputerDecorator extends Computer {

public abstract String getDescription();

public abstract double getPrice();
}

class Windows7Computer extends ComputerDecorator {

Computer computer;
private double price = 30.25;
private String description = "Winodws 7";

public Windows7Computer(Computer computer) {
this.computer = computer;
}

public String getDescription() {
return computer.getDescription() + " + " + description;
}

public double getPrice() {
return computer.getPrice() + price;
}
}

class ExtraMemoryComputer extends ComputerDecorator {

Computer computer;
private double price = 50.75;
private String description = "2G memory";

public ExtraMemoryComputer(Computer computer) {
this.computer = computer;
}

public String getDescription() {
return computer.getDescription() + " + " + description;
}


public double getPrice() {
return computer.getPrice() + price;
}
}

Now we can see that we can create variants of adding anti-virus, extra CD, network card etc and the wrapping works perfectly. In our design, it would have been better to put the reference to Computer in the ComputerDecorator then the concrete subclasses of Decorator but the net effect is the same. Incidentally the classes in java.io package pertaining to various streams and readers/writers use this pattern extensively. Whenever we need to add-on extra behaviour dynamically then Decorator is the answer.

Strategy design pattern

Here is a bit of code which illustrates the Strategy Design Pattern:

package raj;

/**
*
* @author Rajeev
*/
public class StrategyTest {

public static void main(String[] arg) {
Animal dog = new Dog();
Animal cat = new Cat();
Animal donkey = new Donkey();
Animal trickDog = new TrickDog();
dog.makeNoise();
cat.makeNoise();
donkey.makeNoise();
trickDog.makeNoise();
}
}

class Animal {

Noise n;

void makeNoise() {
n.makeNoise();
}
}

class Dog extends Animal {

Dog() {
n = new WoofNoise();
}
}

class TrickDog extends Animal {

TrickDog() {
n = new MeowNoise();
}
}

class Cat extends Animal {

Cat() {
n = new MeowNoise();
}
}

class Donkey extends Animal {

Donkey() {
n = new BrayNoise();
}
}

abstract class Noise {

abstract void makeNoise();
}

class BrayNoise extends Noise {

void makeNoise() {
System.out.println("Bray");
}
}

class WoofNoise extends Noise {

void makeNoise() {
System.out.println("Woof");
}
}

class MeowNoise extends Noise {

void makeNoise() {
System.out.println("Meow");
}
}

The key things is that rather than overriding the makeNoise() method of Animal class in all the subclasses we have abstracted out this behaviour in a separate class as it has a number of variations. The Animal class now HAS-A relationship with this Noise algorithm. All the subclasses of Animal set the proper Noise behaviour in their constructor. This allows our TrickDog to magically start meowing. Also this new Noise class can be used in other situations where appropriate.

Also note that rather than using abstract class for Noise we could have defined it as an interface and then implement it in our concrete Noise classes. The logic becomes:

abstract interface Noise {
abstract void makeNoise();
}

class BrayNoise implements Noise {
void makeNoise() {
System.out.println("Bray");
}
}

... and so on.