The Mediator Pattern

The Mediator pattern facilitates communication between components without having references to each other. It avoids tight coupling between components and helps maintainability.

Let’s say we are building a user interface to visualizes photos. There are multiple components such as the image, the title, the author, the image exif info, the comments, the thumbnail bar, etc. When a user selects a new image, all those components need to be updated. Without the Mediator pattern, the “next” button would call all the components to update them.

public class NextButton {

private Display imageDisplay;
private Label title;
private Label author;
...

public onClick() {
// some code to get the image
imageDisplay.goto(image);
title.set(image);
author.set(image);
// etc...
}
}

We can also imagine that adding a comment would update the title of the image with the total count of comments. It would mean that the comment section has a reference on the title. All those components would be tightly linked.

The Mediator pattern introduces a new component which would be the only one with references to all the different components. Whenever a component needs to communicate with the others, it would send a message to the mediator which then dispatch it to the others.

In our case, the click on “Next” would send an event.

public class NextButton implements UIComponent {

 private EventBroker mediator;

 public void onClick() {
     // some code to get the image
     mediator.publish(new Event("updateImage"));
 }

 public void listen(Event e) {
   // do something when necessary
 }
}

The mediator would then publish the events to all the components that are listening.

public class EventBroker {
    private List<UIComponent> components;

   public void subscribe(UIComponent component) {
     components.add(component);
   }

   public void publish(Event e) {
     components.foreach(it -> it.listen(e));
   }
}

The Iterator Pattern

The iterator pattern allows the client code to traverse data collections without exposing their structure. The client code does not need to know how the data are stored, and how to go from one element to another.

This pattern usually defines an Iterator class which keeps a reference to the current element and is able to go to the next element. Java has its Iterator interface that many collection classes implement.

Iterator<Car> it = mylist.iterator(); // retrieve iterator object from the collection
while (it.hasNext()) { // browse all the elements
   Car car = it.next(); // return the current element and move on the next element
   // ... do something
}

The Interpreter Pattern

The interpreter pattern evaluates textual inputs. It does it by turning it into separated lexical terms (lexing) and interpreting each sequence (parsing). You can think of programming languages, or languages meant to carry information such as XML.

For example, we want to calculate the result of this formula: 1+3+5*7

First, we need to find the terms: [1,3,5,7] and the operations: [+, +, *]

Second, we interpret them into a logical sequence: add(add(1,3),multiply(5,7)).

The idea is to single out terms and operations in order to simplify and make the design flexible to different inputs (ex: term order, etc.)

The Command Pattern

The Command Pattern is useful to implement an instruction to perform a particular action. It contains and encapsulates all the information necessary for the action to be taken. It can allow to create composite commands, to keep track of a sequence of commands, and possibly to undo one of the commands. It can be used in GUI or transactions for example.

Think of a text editor. We can type characters and format them. Each command will implement an interface:

public interface Command {
   void perform();
   void undo();
}

public class Write implements Command {

   private TextEditor editor; // we will assume this class exists.
   private String string;
   private boolean success;

   public Write(TextEditor editor, String string) {
      this.editor = editor;
      this.string = string;
      this.success = false; // by default, a boolean is false, but it does not hurt to make it explicit!
   }

   @Override
   public void perform() {
       editor.write(string);
       success = true;
   }

   @Override
   public void undo() {
      if (success) { // we do not want to undo if the operation failed
        editor.erase(string); // more complex in reality, but not the purpose of this example.
      }
   }
}

public class Formatter implements Command {

  public enum Format {
     BOLD,
     ITALICIZE
  }

   private TextEditor editor;
   private Format format;
   private int startPosition; 
   private int endPosition;
   private boolean success;

   public Formatter(TextEditor editor, Format format, int startPosition, int endPosition) { // could chain with Write.. Chain of responsibility pattern!
      this.editor = editor;
      this.format = format;
      this.startPosition = startPosition;
      this.endPosition = endPosition;
      this.success = false;
   }

   @Override
   public void perform() {
      switch (format) {
         case BOLD:
           success = editor.bold(startPosition, endPosition);
           break;
         case ITALICIZE:
           success = editor.italicize(startPosition, endPosition);
           break;
         default: 
           break;
      }
   }

   @Override
   public void undo() {
      if (!success) return; // we do not want to undo if the operation failed
      switch (format) {
        case BOLD:
          editor.unbold(startPosition, endPosition);
          break;
        case ITALICIZE:
          editor.unbold(startPosition, endPosition);
          break;
        default:
          break;
      }
   }
}

The client code can chain commands or undo, etc.

TextEditor editor = new TextEditor();
Command awesome = new Write(editor, "This is awesome!");
Command author = new Write(editor, "By John Doe");
Command formatAwesome = new Formatter(editor, Formatter.Format.BOLD, 8, 15); 
Command formatAuthor = new Formatter(editor, Formatter.Format.ITALICIZE, 16, 27);

List<Command> cmds = new ArrayList<>();
cmds.add(awesome);
cmds.add(formatAwesome);
cmds.add(author);
cmds.add(formatAuthor);

try {
  cmds.forEach(Command::perform); // run
} catch (Exception e) {
  Collections.reverse(cmds); // reverse the command sequence.
  cmds.forEach(Command::undo); // will undo only those that succeeded.
}

This pattern can be combined with the Chain of Responsibility pattern or the Strategy pattern.

This is awesome! But is it really useful you could ask? What about just calling TextEditor’s methods? True! I was wondering the same. What is really powerful is how we can manage those commands. It can be more complex commands, sequenced, and we can create rollbacks, etc.

The Chain of Responsibility Pattern

The Chain of Responsibility pattern is useful when there is a chain of components that need to accomplish the same operation. Each component may have a default implementation and/or cancel the processing chain.

Let’s say we want to write a class that handles http requests. For each request, we want to log it, verify its authentication, and parse the content. Each operation can be designed as a class implementing the same interface.

public interface HttpRequestHandler {

   HttpRequestHandler next();
   void setNext(HttpRequestHandler next);

   // allows to chain other handlers
   default void add(HttpRequestHandler handler) {
      if (next() != null) {
        next().add(handler);
      } else {
        setNext(handler);
      }
   }; 

   void process(HttpRequest request);
}

public class Logger implements HttpRequestHandler {

   private Log log = ...
   private HttpRequestHandler next;

   // implements getter/setter
   // ...

   public void process(HttpRequest request) {
      log.log(request); // order can changed if we want the operations to start at the end of the chain
      if (next != null) next.process(request);
   }
}

public class Authenticator implements HttpRequestHandler {

    private HttpRequestHandler next;

    // implements getter/setter
    // ...

    public void process(HttpRequest request) {
      if (authenticate(request)) {
         if (next != null) next.process(request);
      }
      // the chain is disrupted if the request does not pass the security check
    }

    private boolean authenticate(HttpRequest request) {
      // ...
    }
}


public class Parser implements HttpRequestHandler {

    private HttpRequestHandler next;

    // implements getter/setter
    // ...

    public void process(HttpRequest request) {
      parse(request);
      if (next != null) next.process(request);
    }

    private void parse(HttpRequest request) {
       // ...
    }
}

The good thing with this design is that we can add more operations without too much effort. Now we can have our client code manipulating the handlers:

public class WebServer {

   public HttpResponse respondTo(HttpRequest request) {
      handlers().handle(request);
   }

   private HttpRequestHandler handlers() {
      Logger logger = new Logger();
      Authenticator auth = new Authenticator();
      Parser parser = new Parser();
      logger.add(auth);
      logger.add(parser);
      return logger;
   }

}

The Flyweight Pattern

The flyweight pattern seeks to avoid redundancy when storing data. It is a space optimization technique that uses less memory by storing data from similar objects.

Let’s say we want to render the movements of an animal on map based on GPS coordinates collected every 10 seconds from an implanted GPS device. The data collected are represented by a list of GpsPoint:

public class GpsPoint {
  private double longitude;
  private double latitude;
  private double altitude;

  // getters/setters
}

Now we may want to track multiple animals on a single map. The number of points can quickly increase. We can use a buffer to keep in memory duplicated points. Indeed, the animal may stay or go back to the same spots. Our buffer can be very simple:

public class Buffer<GpsPoint> {

   private List<GpsPoint> points;

   public boolean contains(GpsPoint point) {
      return points.contains(point); // assume GpsPoint overrode equals() and hashcode()
   }

   // ...
}

We would need a buffer manager or the renderer can manage the buffer. For example, it would check if the point exists in the buffer before adding it:

public class Renderer {

   private Buffer<GpsPoint> buffer;

   public void render(GpsPoint point) {
       if (!buffer.contains(point)) { // does not keep duplicate in memory
          buffer.add(point);
       }

       buffer.forEach(pt -> drawPoint(pt)); // render each point of the buffer
   }

}

Buffer has less points than what the trace has. Simple technique… the most complicated part of this pattern is probably its name 🙂

The Observer Pattern (or Publisher-Subscriber)

The “Gang of Four” defines it as “Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically” (1).

Why would I need such a thing? Let me illustrate the answer.

When I was a teenager, mobile phones were not yet available. My friends and I decided to spend our Saturday afternoon at the mall. We called each other to set up a time and place where to meet. When I got there, I saw no one. After waiting for a while, I decided to leave. Once at home, I called one of my friends who told me they had cancelled. Someone called someone else, who called someone else while the other one called another person, etc. Unfortunately, by the time I was supposed to get the message, I was already in the city bus.

It would have been great to have a Facebook group that we all joined, and get the cancellation message quickly. You see the problem was that the message somehow got lost between friends. Maybe some got busy with other things. Maybe others forgot to update me, or thought someone else had done it before, etc.

That’s where the Observer pattern is useful. My illustration is not a perfect fit though, but let’s say the person who cancelled was the leader of the group. He is the one in command, and he decides what to do. In the Observer pattern, he is usually called the “subject,” and each member of the group “observer.”

The observer decide to get notifications from the subject.

public class GroupLeader {
  public void attach(Observer obs) {
    // add to the list
  };

  public void detach(Observer obs) {
    // remove of the list
  }

  public void notifiy() {
    // go through the list and notify each observer of a change
    for each observer:
      observer.update("this is the new message")
  }
}
public class GroupMember {
  public void update(String message) {
    // do something
  }
}

The advantages are:

  1. Each member receives the same message.
  2. Each member do not need to worry about the others.
  3. Each member can be responsible for their own task

This pattern is a top-bottom behavior. There is only one who can send messages. A better design pattern for group messaging may be the Mediator Pattern where multiple objects can send messages to others. Which one should you choose? It really depends on what you are trying to accomplish.

(1) John Vlissides; Ralph Johnson; Erich Gamma; Richard Helm. Design Patterns: Elements of Reusable Object-Oriented Software. Published by Addison-Wesley Professional, 1994, p. 293

The Visitor Design Pattern

Design patterns are the fun of Object Oriented Programming. It is the artsy side of OOP! In this post, I am illustrating the visitor pattern to understand what it is and what it is meant to be.

When I moved in the US, I asked if doctors visited their patients. I was told it was only for emergency. But in France, it is a common practice. A doctor may have scheduled days to visits patients. His secretary would set up the appointments and let him know where and when.

In the Visitor pattern, the secretary is what the pattern calls “client,” or the dispatcher. She has the list (object structure) of patients (called “elements” which are the data objects) for the day, and calls the patients to make sure they “accept” the doctor (called “visitor” – perform the operation) when he comes for the visit.

The doctor performs a different operation depending on the patient. For example, Fred is a patient who has the flu, and Bob a broken wrist. When the doctor visits Fred, he will prescribe antiobotics, but for Bob, he will ask him to go to the clinic to get a cast.

In pseudo code, the visitor pattern looks like:

for (patient in the list) {
secretary.calls(patient.accept(doctor))
}

class patient {
  function accept(doctor) {
    doctor.performVisit(self)
  }
}

// sub classes
class patientWithFlu {
  function accept(doctor) {
    getMouthMask()
    doctor.performVisit(self)
  }
}
class patientWithBrokenBone {
  function accept(doctor) {
    getTylenol();
    doctor.performVisit(self)
  }
}

class doctor {
  function performVisit(patientWithFlu) {
    checkIfHasFever(patientWithFlu)
    prescribe(patientWithFlu, antiobotics)
  }

  function performVisit(patientWithBrokenBone) {
    checkBone(patientWithBrokenBone)
    prescribe(patientWithBrokenBone, painMedicine)
    putCast(patientWithBrokenBone)
  }
}

Obviously, one of the disavantages is the complexity it brings, but the advantage is the flexbility to change the operations without affecting the data objects. For example, let’s say the regulations change tomorrow and casts are required to be done in clinics. Our traveling doctor cannot do it anymore during his visit. The doctor class is the only one that needs to be changed. The patientWithBrokenBone stay the same.

function performVisit(patientWithBrokenBone) {
  checkBone(patientWithBrokenBone)
  prescribe(patientWithBrokenBone, painMedicine)
  giveContactInfo(patientWithBrokenBone, clinicA)
}

In Summary:
Client
-> calls each element of a list to accept the visitor

Element (each element requires a different type of operation)
-> accepts the visitor and let him do what he is supposed to do

Visitor
-> performs the operation with the element