Design Pattern: Observer Pattern

The Observer is known as a behavioural pattern, as it’s used to form relationships between objects at runtime.

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Let’s take a look at the classic diagram definition of  the observer:

One or more Observers are interested in the state of a Subject and register their interest with the Subject by attaching themselves. When something changes in our Subject, a notify message is sent, which calls the update method in each Observer.
When the Observer is no longer interested in the Subject’s state, they can simply detatchthemselves.

So How Does It Work In Java?

In our example, the subject will be a DataStore, with a Screen class as the observer.

First, let’s make our DataStore class observable by extending the java.util.Observable class. This means that our DataStore has all the methods and functionality available to make it a Subject, according to our pattern.

import java.util.Observable;

public class DataStore extends Observable
{
	
	private String data;
	
	public String getData()
	{
		return data;
	}
	
	public void setData(String data)
	{
		this.data =data;
		//mark the observable as changed
		setChanged();
	}	
}

 

You’ll notice that we have called the setChanged() method of the Observable. This is necessary in order for the call to notify observers to send out the update. Without this set, the Observable will see no reason to send out the update.

Next, let’s create our Observer. To do this, all we need to do is implement the Observer interface which forces us to write an update method, to deal with changes in the Observable’s state.

public class Screen implements Observer {

	@Override
	public void update(Observable o, Object arg) {

		//act on the update
	}

}

Adding our Screen as an observer to the DataStore is simple:

Screen screen = new Screen();

DataStore dataStore = new DataStore();
//register observer 
dataStore.addObserver(screen);

When the data changes, we want to notify all observers of this object. To do this, we just need to call the notifyObservers method when we want an update sent out

//send a notification
dataStore.notifyObservers();

Pros:

To pass data onto the observers, our subject doesn’t need to know who needs to know. Instead, everything is done through a common interface, and the notify method just calls all the objects out there that have registered their interest. This is a very powerful decoupling – meaning that any object can simply implement the Observer interface and get updates from the Subject.

Cons:

It can be difficult to see the path through the code, unless you are debugging. As such, you should be careful not to have chains of observers (observers acting as subjects). Also, watch out for memory leaks as the subject will hold a reference to the observer unless it has deregistered.

FacebookTwitterGoogle+Share

Design Pattern: Facade

Like the Adapter pattern, Facade is known as a structural pattern, as it’s used to identifying a simple way to realize relationships between entities.

Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use.

The diagram definition of the Facade pattern is quite simple – all you’re really doing is insulating client from the subsystem:

So How Does It Work In Java?

Let’s put together a simple example in Java code to illustrate the pattern. Let’s take a travel agent site for example, that allows you to book hotels and flights.

We have a HotelBooker:

public class HotelBooker
{

  public ArrayList<Hotel> getHotelNamesFor(Date from, Date to) 
  {
      //returns hotels available in the particular date range

  }

}

And a FlightBooker:

public class FlightBooker
{

  public ArrayList<Flight> getFlightsFor(Date from, Date to) 
  {
      //returns flights available in the particular date range

  }

}

Both of these have Hotel and Flight datatypes, which the client has knowledge about. They could be provided in the same package as the Facade for example.

The TravelFacade class allows the user to get their Hotel and Flight information in one call:

 

public class TravelFacade
{

   private HotelBooker hotelBooker;
   private FlightBooker flightBooker; 

  public void getFlightsAndHotels(Date from, Data to)
  {
         ArrayList<Flight> flights = flightBooker.getFlightsFor(from, to);
         ArrayList<Hotel> hotels = hotelBooker.getHotelsFor(from, to);

         //process and return

   }

}

All that the client needs to worry about is the Facade class:

public class Client
{

   public static void main(String[] args)
   {
        TravelFacade facade = new TravelFacade(); 
        facade.getFlightsAndHotels(from, to);
   }
}

Downsides

By introducing the Facade into your code, you will be hardwiring subsystems into the Facade. This is fine if the subsystem never changes, but if it does, your Facade could be broken. Therefore, developers working on the subsystem should be made aware of any Facade around their code.

Adapter VS Facade

Similarity:

Like the adapter pattern, the Facade can be used to hide the inner workings of a third party library, or some legacy code.  All that the client needs to do is interact with the Facade, and not the subsystem that it is encompassing.

Difference:

Facade defines a new interface, whereas Adapter uses an old interface. Remember that Adapter makes two existing interfaces work together as opposed to defining an entirely new one. Adapter and Facade are both wrappers; but they are different kinds of wrappers. The intent of Facade is to produce a simpler interface, and the intent of Adapter is to design to an existing interface. While Facade routinely wraps multiple objects and Adapter wraps a single object; Facade could front-end a single complex object and Adapter could wrap several legacy objects.

Thanks to James Sugrue‘s artical: Design Patterns Uncovered: The Facade Pattern

Design Pattern: Adapter

The Adapter is known as a structural pattern, as it’s used to identifying a simple way to realize relationships between entities.

Convert the interface of a class into another interface clients expect. Adapter helps two incompatible interfaces  to work together.

So How Does It Work In Java?

The following example shows a simple implementation of the pattern. Consider that we have a third party library that provides sorting functionality through it’s NumberSorter class. This is our Adaptee.

/* 
 * This is our adaptee, a third party implementation of a 
 * number sorter that deals with Lists, not arrays.
 */
public class NumberSorter
{
   public List<Integer> sort(List<Integer> numbers)
   {
      //sort and return
      return new ArrayList<Integer>();
   }

}

Our Client deals with primitive arrays rather than Lists. For the sake of this example, lets say we can’t change the client to use Lists. 

int[] numbers = new int[]{34, 2, 4, 12, 1};

Sorter sorter = new SortListAdapter();
sorter.sort(numbers);

We’ve provided a Sorter interface that expects the client input. This is our target.

//this is our Target interface
public interface Sorter
{
   public int[] sort(int[] numbers);
}

Finally, the SortListAdapter implements our target interface and deals with our adaptee, NumberSorter

public class SortListAdapter implements Sorter
{

   @Override
   public int[] sort(int[] numbers)
   {
      //convert the array to a List
      List<Integer> numberList = new ArrayList<Integer>();
      
      //call the adapter 
      NumberSorter sorter = new NumberSorter();
      numberList = sorter.sort(numberList);
      
      //convert the list back to an array and return 
      
      return sortedNumbers;
   }
   
}

Downsides:

Some say that the Adapter pattern is just a fix for a badly designed system, which didn’t consider all possibilties. While this is a fair point, it is an important part of a pluggable architecture.  It can also add a level of complexity to your code, making debugging more difficult.

Design Pattern: Factory

For example a graphical application works with shapes.

Client: Drawing framework

Products: Different shapes

Abstract class/Interface: Shape class (The Shape class defines the draw and move operations which must be implemented by the concrete shapes.)

1. Client creates a new Circle

2. The framework receives the shape type as a string parameter, it asks the factory to create a new shape sending the parameter received from menu.

3. The factory creates a new circle and returns it to the framework, casted to an abstract shape.

4. Then the framework uses the object as casted to the abstract class without being aware of the concrete object type.

The advantage is obvious: New shapes can be added without changing a single line of code in the framework(the client code that uses the shapes from the factory).

//naive version

public abstract class Shape {
	public void draw();
}

public class Circle extends Shape{
	public void draw(){
		System.out.println("Draw a circle");
	}

}

public class Rectangle implements Product{
	public void getName(){
		System.out.println("Draw a rectangle");
	}
}

public class Factory {
	public Shape createProduct(String type){
		if(type.equals("Circle")){
			return new Circle();
		}
                if(type.equals("Rectangle")){
			return new Rectangle();
		}
                else
			return null;
	}
}

public class DrawingPanel{
        Factory f= new Factory();
	f.createProduct("Circle").draw();
	f.createProduct("Rectangle").draw();
}

The problem here is that once we add a new concrete product call we should modify the Factory class. It is not very flexible.