The Decorator Pattern

The idea is to augment an existing class with new functionalities without rewriting the existing code. There are two possibilities to do it:

Solution 1: Inherit if the class is not final.

Solution 2: Add a decorator class using composition.

Let’s say we want to program a draw shapes. We can create a Display interface that will be implemented by all of our classes.

public interface Display {

  public void draw();

}

Our basic class draws the shape

public class SimpleDisplay implements Display {

   public void draw() {
     // draw shape
   }

}

Now we want to fill the shape. We can extend what SimpleDisplay does with another class:

public class FillerDisplay {

   private Display display;

   public FillerDisplay(Display display) {
     this.display = display;
   }

   public void draw() {
     fill();
     display.draw();
   }

}

We can also add a zoom effect:

public class ZoomDisplay {

   private Display display;

   public ZoomDisplay(Display display) {
     this.display = display;
   }

   public void draw() {
      zoom();
      display.draw(); 
   }

}

So we can combine those decorators to obtain the result we want:

// a simple display
Display simple = new SimpleDisplay();

// a display filling the shape
Display fill = new FillerDisplay(new SimpleDisplay());

// a display that can zoom
Display zoom = new ZoomDisplay(new FillerDisplay(new SimpleDisplay()));

Notice we do not have to have a filler. A display can simply draw a shape and zoom. There are also ways to simplify the creation of the objects.

What can be trickier is accessing methods in one of the layers. For example, we can imagine that we want the FillerDisplay to use an image to fill the shape. In that case, we would add a method called setImageBackground() but it would be specific to FillerDisplay. To access that method, we would need to implement a getDisplay() in each layer, and we would have a code that looks like:

display.getDisplay().getDisplay()... getDisplay().setImageBackground(img)

which is not … very pretty … (Coding is art after all). What’s possible is to create a “shortcut” method in the client code if it is used frequently:

private Display getFillerDisplay() {
   return display.getDisplay().getDisplay()... getDisplay();
}

It can be lengthy code if each display is a generic:

LayerDisplay<ZoomDisplay<FillerDisplay<RandomDisplay<SimpleDisplay>>>>> display;

hmmm… so good. 🙂

Author: Toujon Lyfoung

This paragraph is supposed to be the place where I put my credentials and achievements. In my opinion, degrees and jobs do not tell much about a person. If you want to know me, read my posts! Blogging has been fun. I do not pretend to do much. I am simply processing, tracking and sharing my reflection. Comments are definitely welcomed to help me continue in my learning.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s