Design patterns represent the best practices used by experienced object-oriented software developers. Design patterns are solutions to general problems that software developers faced during software development. These solutions were obtained by trial and error by numerous software developers over quite a substantial period of time.

This tutorial will take you through step by step approach and examples using Java while learning Design Pattern concepts.

Three Types of Design Patterns

Design patterns are divided into three fundamental groups: Behavioral Patterns, Creational Patterns, and Structural Patterns.

  • Behavioral Patterns: Abstract Factory, Builder, Factory Method, Prototype, and Singleton.
  • Creational Patterns: Adapter, Bridge, Composite, Decorator, Facade, Flyweight, and Proxy
  • Structural Patterns: Chain of Resp., Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template, and Visitor

Seven Principles of Design Patterns

Open Close Principle

Software entities like classes, modules and functions should be open for extension but closed for modifications.

OPC is a generic principle. You can consider it when writing your classes to make sure that when you need to extend their behavior you don’t have to change the class but to extend it. The same principle can be applied to modules, packages, and libraries. If you have a library containing a set of classes there are many reasons for which you’ll prefer to extend it without changing the code that was already written (backward compatibility, regression testing, etc.). This is why we have to make sure our modules follow Open Closed Principle.

When referring to the classes Open Close Principle can be ensured by the use of Abstract Classes and concrete classes for implementing their behavior. This will enforce having Concrete Classes extending Abstract Classes instead of changing them. Some particular cases of this are Template Patterns and Strategy Patterns.

Single Responsibility Principle

A class should have only one reason to change.

In this context, responsibility is considered to be one reason to change. This principle states that if we have 2 reasons to change for a class, we have to split the functionality into two classes. Each class will handle only one responsibility and in the future, if we need to make one change we are going to make it in the class which handles it. When we need to make a change in a class having more responsibilities the change might affect the other functionality of the classes.

The Single Responsibility Principle was introduced by Tom DeMarco in his book Structured Analysis and Systems Specification, 1979. Robert Martin reinterpreted the concept and defined responsibility as a reason to change.

Liskov Substitution Principle

Derived types must be completely substitutable for their base types.

This principle is just an extension of the Open Close Principle in terms of behavior meaning that we must make sure that new derived classes are extending the base classes without changing their behavior. The new derived classes should be able to replace the base classes without any change in the code.

Liskov’s Substitution Principle was introduced by Barbara Liskov in a 1987 Conference on Object-Oriented Programming Systems Languages and Applications, in Data abstraction and hierarchy

Dependency Inversion Principle

High-level modules should not depend on low-level modules. Both should depend on abstractions.
Abstractions should not depend on details. Details should depend on abstractions.

The Dependency Inversion Principle states that we should decouple high-level modules from low-level modules, introducing an abstraction layer between the high-level classes and low-level classes. Furthermore, it inverts the dependency: instead of writing our abstractions based on details, we should write the details based on abstractions.

Dependency Inversion or Inversion of Control is a better-known term referring to the way in which the dependencies are realized. In a classical way when a software module(class, framework, etc.) needs some other module, it initializes and holds a direct reference to it. This will make the 2 modules tight coupled. In order to decouple them the first module will provide a hook(a property, parameter, etc.) and an external module controlling the dependencies will inject the reference to the second one.

By applying the Dependency Inversion the modules can be easily changed by other modules just by changing the dependency module. Factories and Abstract Factories can be used as dependency frameworks, but there are specialized frameworks for that, known as Inversion of Control Container.

Interface Segregation Principle

Clients should not be forced to depend upon interfaces that they don’t use.

This principle teaches us to take care of how we write our interfaces. When we write our interfaces we should take care to add only methods that should be there. If we add methods that should not be there the classes implementing the interface will have to implement those methods as well. For example, if we create an interface called Worker and add a method lunch break, all the workers will have to implement it. What if the worker is a robot?

In conclusion, Interfaces containing methods that are not specific to it are called polluted or fat interfaces. We should avoid them.

Law of Demeter(Principle of Least Knowledge)

Only talk to your immediate friends

One never calls a method on an object you got from another call nor on a global object. This helps a lot later when you ReFactor the code.

PeterVanRooijen posted the following description of the LawOfDemeter to Usenet:

  • Your method can call other methods in its class directly
  • Your method can call methods on its own fields directly (but not on the fields’ fields)
  • When your method takes parameters, your method can call methods on those parameters directly.
  • When your method creates local objects, that method can call methods on the local objects.

but

  • One should not call methods on a global object (but it can be passed as a parameter ?)
  • One should not have a chain of messages a.getB().getC().doSomething() in some class other than a’s class.

Composite Reuse Principle

Favor delegation over inheritance as a reuse mechanism

Many design patterns are based on delegation rather than inheritance as a reuse mechanism. Delegation can be seen as a reuse mechanism at the object level, while inheritance is a reuse mechanism at the class level.

The 23 Gang of Three Design Patterns

Behavioral Patterns

Factory Pattern
Motivation

The Factory Design Pattern is probably the most used design pattern in modern programming languages like Java and C#. It comes in different variants and implementations. If you are searching for it, most likely, you’ll find references about the GoF patterns: Factory Method and Abstract Factory.

Intent
  • creates objects without exposing the instantiation logic to the client.
  • refers to the newly created object through a common interface
Implementation

Examples

Those are also known as parameterized Factories. The generating method can be written so that it can generate more types of Product objects, using a condition (entered as a method parameter or read from some global configuration parameters - see abstract factory pattern) to identify the type of the object that should be created, as below:

public class ProductFactory {
    public Product createProduct(String ProductID) {
        if ( id == ID1 ) {
            return new OneProduct();
        } else if ( id == ID2 ) {
            return new AnotherProduct();
        }
        ... // so on for the other Ids
        return null; //if the id doesn't have any of the expected values
    }
    ...
}

This implementation is the most simple and intuitive (Let’s call it noob implementation). The problem here is that once we add a new concrete product call we should modify the Factory class. It is not very flexible and it violates the open close principle. Of course, we can subclass the factory class, but let’s not forget that the factory class is usually used as a singleton. Subclassing it means replacing all the factory class references everywhere through the code.

If you can use reflection, for example in Java or .NET languages, you can register new product classes to the factory without even changing the factory itself. For creating objects inside the factory class without knowing the object type we keep a map between the productID and the class type of the product. In this case, when a new product is added to the application it has to be registered with the factory. This operation doesn’t require any change in the factory class code.

class ProductFactory {
    public void registerProduct (String productID, Class productClass) {
        registeredProducts.put(productID, productClass);
    }

    public Product createProduct(String productID) {
        Class productClass = (Class)registeredProducts.get(productID);
        Constructor productConstructor = Class.getDeclaredConstructor(new Class[] { String.class });
        return (Product)productConstructor.newInstance(new Object[] { });
    }

    private Map<String, Product> registeredProducts = new HashMap<String, Product>();
}
Abstract Factory
Motivation

Modularization is a big issue in today’s programming. Programmers all over the world are trying to avoid the idea of adding code to existing classes in order to make them support encapsulating more general information. Take the case of an information manager who manages phone numbers. Phone numbers have a particular rule on which they get generated depending on areas and countries. If at some point the application should be changed in order to support adding numbers from a new country, the code of the application would have to be changed and it would become more and more complicated.

In order to prevent it, the Abstract Factory design pattern is used. Using this pattern a framework is defined, which produces objects that follow a general pattern and at runtime, this factory is paired with any concrete factory to produce objects that follow the pattern of a certain country. In other words, the Abstract Factory is a super-factory that creates other factories (Factory of factories).

Intent
  • Abstract Factory offers the interface for creating a family of related objects, without explicitly specifying their classes.
Implementation

The pattern basically works as shown below, in the UML diagram:

The classes that participate in the Abstract Factory pattern are:

  • AbstractFactory - declares an interface for operations that create abstract products.
  • ConcreteFactory - implements operations to create concrete products.
  • AbstractProduct - declares an interface for a type of product object.
  • Product - defines a product to be created by the corresponding ConcreteFactory; it implements the AbstractProduct interface.
  • Client - uses the interfaces declared by the AbstractFactory and AbstractProduct classes.
Examples

Look & Feel Example

Look & Feel Abstract Factory is the most common example. For example, a GUI framework should support several looks and feel themes, such as Motif and Windows look. Each style defines different looks and behaviors for each type of control: Buttons and Edit Boxes. In order to avoid hardcoding it for each type of control, we define an abstract class LookAndFeel. These calls will instantiate, depending on a configuration parameter in the application of one of the concrete factories: WindowsLookAndFeel or MotifLookAndFeel. Each request for a new object will be delegated to the instantiated concrete factory which will return the controls with the specific flavor

Singleton Pattern
Motivation

Sometimes it’s important to have only one instance for a class. For example, in a system there should be only one window manager (or only a file system or only a print spooler). Usually singletons are used for centralized management of internal or external resources and they provide a global point of access to themselves.

The singleton pattern is one of the simplest design patterns: it involves only one class which is responsible to instantiate itself, to make sure it creates not more than one instance; at the same time it provides a global point of access to that instance. In this case, the same instance can be used from everywhere, being impossible to invoke directly the constructor each time.

Indent
  • Ensure that only one instance of a class is created.
  • Provide a global point of access to the object.
Implementation

Examples
class Singleton {
    private Singleton() {
        // ...
    }

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

    public void doSomething() {
        // ...
    }

    private static Singleton instance;
Builder Pattern
Motivation

The more complex an application is the complexity of classes and objects used increases. Complex objects are made of parts produced by other objects that need special care when being built. An application might need a mechanism for building complex objects that is independent from the ones that make up the object. If this is the problem you are being confronted with, you might want to try using the Builder (or Adaptive Builder) design pattern.

This pattern allows a client object to construct a complex object by specifying only its type and content, being shielded from the details related to the object’s representation. This way the construction process can be used to create different representations. The logic of this process is isolated form the actual steps used in creating the complex object, so the process can be used again to create a different object form the same set of simple objects as the first one.

Indent
  • Defines an instance for creating an object but letting subclasses decide which class to instantiate
  • Refers to the newly created object through a common interface
Implementation

Example - A RTF Converter Application

The Client needs to convert a document from RTF format to ASCII format. Therefore, it calls the method createASCIIText which takes as a parameter the document that will be converted. This method calls the concrete builder, ASCIIConverter, that extends the Builder, TextConverter, and overrides its two methods for converting characters and paragraphs, and also the Director, RTFReader, that parses the document and calls the builder’s methods depending on the type of token encountered. The product, the ASCIIText, is built step by step, by appending converted characters.

//Abstract Builder
public class abstract class TextConverter {
    abstract void convertCharacter(char c);
    abstract void convertParagraph();
}

// Product
public class ASCIIText {
    public void append(char c){ //Implement the code here }
}

//Concrete Builder
class ASCIIConverter extends TextConverter {
    ASCIIText asciiTextObj; //resulting product

    /*converts a character to target representation and appends to the resulting*/
    voidconvertCharacter(char c) {
        char asciiChar = new Character(c).charValue();
        //gets the ascii character
        asciiTextObj.append(asciiChar);
    }

    void convertParagraph() { }
    ASCIIText getResult() {
        return asciiTextObj;
    }
}

//This class abstracts the document object
public class Document {
    static int value;
    char token;
    public char getNextToken() {
        //Get the next token
        return token;
    }
}

//Director
public class RTFReader{
    private static final char EOF='0'; //Delimitor for End of File
    final char CHAR='c';
    final char PARA='p';
    char t;
    TextConverter builder;
    RTFReader(TextConverter obj) {
        builder=obj;
    }
    void parseRTF(Document doc) {
        while ( (t=doc.getNextToken())!= EOF ) {
            switch ( t ) {
                case CHAR: builder.convertCharacter(t);
                case PARA: builder.convertParagraph();
            }
        }
    }
}

//Client
public class Client{
    void createASCIIText(Document doc) {
        ASCIIConverter asciiBuilder = new ASCIIConverter();
        RTFReader rtfReader = new RTFReader(asciiBuilder);
        rtfReader.parseRTF(doc);
        ASCIIText asciiText = asciiBuilder.getResult();
    }
    public static void main(String args[]) {
        Client client = new Client();
        Document doc = new Document();
        client.createASCIIText(doc);
    System.out.println("This is an example of Builder Pattern");
    }
}
Prototype Pattern
Motivation

Today’s programming is all about costs. Saving is a big issue when it comes to using computer resources, so programmers are doing their best to find ways of improving performance When we talk about object creation we can find a better way to have new objects: cloning. To this idea one particular design pattern is related: rather than creating it uses cloning. If the cost of creating a new object is large and creation is resource-intensive, we clone the object.

The Prototype design pattern is the one in question. It allows an object to create customized objects without knowing their class or any details of how to create them. Up to this point, it sounds a lot like the Factory Method pattern, the difference being the fact that for the Factory the palette of prototypical objects never contains more than one object.

Intent
  • specifying the kind of objects to create using a prototypical instance
  • creating new objects by copying this prototype
Implementation

Example
public class Prototype implements Cloneable {
    public Object clone() throws CloneNotSupportedException {
        Prototype proto = (Prototype) super.clone();
        return proto;
    }
}  

public class Client {
    public static void main(String arg[]) throws CloneNotSupportedException {
        Prototype obj1= new Prototype ();
        Prototype obj2 = (Prototype)obj1.clone();
    }
}

Creational Patterns

Adapter Pattern
Motivation

The adapter pattern is adapting between classes and objects. Like any adapter in the real world, it is used to be an interface, a bridge between two objects. In real-world we have adapters for power supplies, adapters for camera memory cards, and so on. Probably everyone has seen some adapters for memory cards. If you can not plug in the camera memory in your laptop you can use an adapter. You plug the camera memory in the adapter and the adapter into the laptop slot. That’s it, it’s really simple.

What about software development? It’s the same. Can you imagine a situation when you have some class expecting some type of object and you have an object offering the same features, but exposing a different interface? Of course, you want to use both of them so you don’t implement again one of them, and you don’t want to change existing classes, so why not create an adapter…

Intent
  • Convert the interface of a class into another interface clients expect.
  • Adapter lets classes work together, which could not otherwise because of incompatible interfaces.
Implementation

Examples
public class Adaptee {
    public void method1() {
       System.out.println("This is Adaptee's method!");
    }
}

public interface Target {
    public void method1();
    public void method2();
}

public class Adapter extends Adaptee implements Target {
    @Override
    public void method2() {
        System.out.println("This is the Adapter's method!");
    }
}

public class Client {
    public static void main(String[] args) {
        Targetable target = new Adapter();
        target.method1();
        target.method2();
    }
}
Decorator Pattern
Motivation

Extending an object’s functionality can be done statically (at compile time) by using inheritance however it might be necessary to extend an object’s functionality dynamically (at runtime) as an object is used.

Consider the typical example of a graphical window. To extend the functionality of the graphical window for example by adding a frame to the window, would require extending the window class to create a FramedWindow class. To create a framed window it is necessary to create an object from the FramedWindow class. However, it would be impossible to start with a plain window and extend its functionality at runtime to become a framed window.

Intent
  • The intent of this pattern is to add additional responsibilities dynamically to an object.
Implementation

Example
public interface Component {
    public void doOperation();
}

public class ConcreteComponent implements Component {
    @Override
    public void doOperation() {
        System.out.println("the original method!");
    }
}

public class Decorator implements Component {
    private Component component;

    public Decorator(Component component){
        super();
        this.component = component;
    }

    @Override
    public void doOperation() {
        System.out.println("Before doOperation()");
        component.doOperation();
        System.out.println("After doOperation()");
    }
}  

public class DecoratorTest {
    public static void main(String[] args) {
        Component component = new ConcreteComponent();
        Component decorator = new Decorator(component);
        decorator.doOperation();
    }
}
Proxy Pattern
Motivation

Sometimes we need the ability to control access to an object. For example, if we need to use only a few methods for some costly objects we’ll initialize those objects when we need them entirely. Until that point, we can use some light objects exposing the same interface as the heavy objects. These light objects are called proxies and they will instantiate those heavy objects when they really need and by then we’ll use some light objects instead.

This ability to control the access to an object can be required for a variety of reasons: controlling when a costly object needs to be instantiated and initialized, giving different access rights to an object, as well as providing a sophisticated means of accessing and referencing objects running in other processes, on other machines.

Consider for example an image viewer program. An image viewer program must be able to list and display high-resolution photo objects that are in a folder, but how often does someone open a folder and view all the images inside? Sometimes you will be looking for a particular photo, sometimes you will only want to see an image name. The image viewer must be able to list all photo objects, but the photo objects must not be loaded into memory until they are required to be rendered.

Intent
  • The intent of this pattern is to provide a “Placeholder” for an object to control references to it.
Implementation

Example
public interface Subject {
    public void method();
}

public class RealSubject implements Subject {
    @Override
    public void method() {
        System.out.println("the original method!");
    }
}

public class Proxy implements Subject {
    private Subject subject;

    public Proxy() {
        super();
        this.subject = new RealSubject();
    }

    @Override
    public void method() {
        before();
        source.method();
        atfer();
    }

    private void before() {
        System.out.println("Before proxy!");
    }

    private void atfer() {
        System.out.println("After proxy!");
    }
}  

public class Client {
    public static void main(String[] args) {
        Subject subject = new Proxy();
        subject.method();
    }
}
Facade Pattern
Motivation

A Facade is used when an easier or simpler interface to an underlying object is desired. Alternatively, an adapter can be used when the wrapper must respect a particular interface and must support polymorphic behavior. A decorator makes it possible to add or alter the behavior of an interface at run-time.

Implementation

Example
public class CPU {
    public void startup(){
        System.out.println("CPU Startup!");
    }

    public void shutdown(){
        System.out.println("CPU Shutdown!");
    }
}

public class Memory {
    public void startup(){
        System.out.println("Memory Startup!");
    }

    public void shutdown(){
        System.out.println("Memory Shutdown!");
    }
}

public class Disk {
    public void startup(){
        System.out.println("Disk Startup!");
    }

    public void shutdown(){
        System.out.println("Disk Shutdown!");
    }
}

public class Computer {
    public Computer() {
        cpu = new CPU();
        memory = new Memory();
        disk = new Disk();
    }  

    public void startup() {
        cpu.startup();
        memory.startup();
        disk.startup();
    }  

    public void shutdown() {
        cpu.shutdown();
        memory.shutdown();
        disk.shutdown();
    }

    private CPU cpu;
    private Memory memory;
    private Disk disk;
}  

public class User {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.startup();
        computer.shutdown();
    }
}

The User class won’t care what’s objects in the Computer class. The Computer class will maintain the relationship between CPU, Memory, and Disk.

The Computer class decouples the class among CPU, Memory, and Disk.

Bridge Pattern
Motivation

Sometimes an abstraction should have different implementations; consider an object that handles the persistence of objects over different platforms using either relational databases or file system structures (files and folders). A simple implementation might choose to extend the object itself to implement the functionality for both the file system and RDBMS. However this implementation would create a problem; Inheritance binds an implementation to the abstraction and thus it would be difficult to modify, extend, and reuse abstraction and implementation independently.

Indent
  • The intent of this pattern is to decouple an abstraction from implementation so that the two can vary independently.
Implementation

Example

JDBC is a typical application of Bridge Pattern.

Composite Pattern
Motivation

There are times when a program needs to manipulate a tree data structure and it is necessary to treat both Branches as well as Leaf Nodes uniformly. Consider for example a program that manipulates a file system. A file system is a tree structure that contains Branches which are Folders as well as Leaf nodes which are Files. Note that a folder object usually contains one or more files or folder objects and thus is a complex object whereas a file is a simple object. Note also that since files and folders have many operations and attributes in common, such as moving and copying a file or a folder, and listing file or folder attributes such as file name and size, it would be easier and more convenient to treat both file and folder objects uniformly by defining a File System Resource Interface.

Indent
  • The intent of this pattern is to compose objects into tree structures to represent part-whole hierarchies.
    Composite lets clients treat individual objects and compositions of objects uniformly.
Implementation

Example

Example - Graphics Drawing Editor.

In graphics editors, a shape can be basic or complex. An example of a simple shape is a line, whereas a complex shape is a rectangle that is made of four-line objects. Since shapes have many operations in common such as rendering the shape to screen, and since shapes follow a part-whole hierarchy, a composite pattern can be used to enable the program to deal with all shapes uniformly.

In the example we can see the following actors:

  • Shape (Component) - Shape is the abstraction for Lines, Rectangles (leaves) and ComplexShapes (composites).
  • Line, Rectangle (Leafs) - objects that have no children. They implement services described by the Shape interface.
  • ComplexShape (Composite) - A Composite stores child Shapes in addition to implementing methods defined by the Shape interface.
  • GraphicsEditor (Client) - The GraphicsEditor manipulates Shapes in the hierarchy.
Flyweight Pattern
Motivation

Some programs require a large number of objects that have some shared state among them. Consider for example a game of war, where there is a large number of soldier objects; a soldier object maintains the graphical representation of a soldier, soldier behavior such as motion, and firing weapons, in addition, the soldier’s health and location in the war terrain. Creating a large number of soldier objects is a necessity however it would incur a huge memory cost. Note that although the representation and behavior of a soldier are the same their health and location can vary greatly.

Indent
  • The intent of this pattern is to use sharing to support a large number of objects that have part of their internal state in common whereas the other part of the state can vary.
Implementation

Example

One of the typical uses of Flyweight Pattern is Constant Pool in Java, such as String Pool.

String s1 = Hello, world!;
String s2 = Hello, world!;
System.out.println(s1==s2); // true.

If you want to get more information about String Pool in Java, you can see this post.

Structural Patterns

Strategy Pattern
Motivation

There are common situations when classes differ only in their behavior. For these cases is a good idea to isolate the algorithms in separate classes in order to have the ability to select different algorithms at runtime.

Indent
  • Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
Implementation

Example

public class RobotTest {
    public static void main(String[] args) {
        Robot r1 = new Robot("Big Robot");
        Robot r2 = new Robot("George v.2.1");
        Robot r3 = new Robot("R2");

        r1.setBehaviour(new AgressiveBehaviour());
        r2.setBehaviour(new DefensiveBehaviour());
        r3.setBehaviour(new NormalBehaviour());

        r1.move();
        r2.move();
        r3.move();
    }
}
Template Method Pattern
Motivation

If we take a look at the dictionary definition of a template we can see that a template is a preset format, used as a starting point for a particular application so that the format does not have to be recreated each time it is used.
On the same idea is the template method is based. A template method defines an algorithm in a base class using abstract operations that subclasses override to provide concrete behavior.

Indent
  • Define the skeleton of an algorithm in an operation, deferring some steps to subclasses.
  • Template Method lets subclasses redefine certain steps of an algorithm without letting them to change the algorithm’s structure.
Implementation

Example

public abstract class Trip {
    public final void performTrip(){
         doComingTransport();
         doDayA();
         doDayB();
         doDayC();
         doReturningTransport
    }
    public abstract void doComingTransport();
    public abstract void doDayA();
    public abstract void doDayB();
    public abstract void doDayC();
    public abstract void doReturningTransport();
}

public class PackageA extends Trip {
    public void doComingTransport() {
         System.out.println("The turists are comming by air ...");
    }
    public void doDayA() {
         System.out.println("The turists are visiting the aquarium ...");
    }
    public void doDayB() {
         System.out.println("The turists are going to the beach ...");
    }
    public void doDayC() {
         System.out.println("The turists are going to mountains ...");
    }
    public void doReturningTransport() {
         System.out.println("The turists are going home by air ...");
    }
}
public class PackageB extends Trip {
    public void doComingTransport() {
         System.out.println("The turists are comming by train ...");
    }
    public void doDayA() {
         System.out.println("The turists are visiting the mountain ...");
    }
    public void doDayB() {
         System.out.println("The turists are going to the beach ...");
    }
    public void doDayC() {
         System.out.println("The turists are going to zoo ...");
    }
    public void doReturningTransport() {
         System.out.println("The turists are going home by train ...");
    }
}
Observer Pattern
Motivation

The cases when certain objects need to be informed about the changes that occurred in other objects are frequent. To have a good design means to decouple as much as possible and reduce the dependencies. The Observer Design Pattern can be used whenever a subject has to be observed by one or more observers.

Let’s assume we have a stock system that provides data for several types of clients. We want to have a client implemented as a web-based application but in near future, we need to add clients for mobile devices, Palm or Pocket PC, or to have a system to notify the users with SMS alerts. Now it’s simple to see what we need from the observer pattern: we need to separate the subject(stocks server) from its observers(client applications) in such a way that adding a new observer will be transparent for the server.

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

Example
public abstract class Observable {
    public void attach(Observer observer) {
        observers.add(observer);
    }

    public void detach(Observer observer) {
        observers.remove(observer);
    }

    public void notify() {
        Enumeration&amp;amp;lt;Observer&amp;amp;gt; enumo = vector.elements();
        while( enumo.hasMoreElements() ){
            enumo.nextElement().update();
        }
    }

    private List&amp;amp;lt;Observer&amp;amp;gt; observers = new Vector&amp;amp;lt;Observer&amp;amp;gt;();
}

public class ConcreteObservable extends Observable {
    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    private State state;
}

public interface Observer {
    public void update();
} 

public class ConcreteObserverA implements Observer {
    @Override
    public void update() {
        System.out.println("ConcreteObserverA has received!");
    }
}

public class ConcreteObserverB implements Observer {
    @Override
    public void update() {
        System.out.println("ConcreteObserverB has received!");
    }
}
Iterator Pattern
Motivation

One of the most common data structures in software development is what is generic called a collection. A collection is just a grouping of some objects. They can have the same type or they can be all cast to a base type-like object. A collection can be a list, an array, or a tree, and the examples can continue.

But what is more important is that a collection should provide a way to access its elements without exposing its internal structure. We should have a mechanism to traverse in the same way a list or an array. It doesn’t matter how they are internally represented.

The idea of the iterator pattern is to take the responsibility of accessing and passing through the objects of the collection and put it in the iterator object. The iterator object will maintain the state of the iteration, keeping track of the current item and having a way of identifying what elements are next to be iterated.

Indent
  • Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
  • The abstraction provided by the iterator pattern allows you to modify the collection implementation without making any changes outside of the collection. It enables you to create a general-purpose GUI component that will be able to iterate through any collection of the application.
Implementation

Example
public interface Iterator {
    public Object first();
    public Object next();
    public boolean hasNext();
    public Object currentItem();
}

public class ConcreteIterator implements Iterator {
    public ConcreteIterator(Collection collection){
        this.collection = collection;
        currentIndex = 0;
    }

    @Override
    public Object first() {
        return collection.get(0);
    }

    @Override
    public Object currentItem() {
        if ( currentIndex == collection.size() ) {
            return null;
        }
        return collection.get(currentIndex ++);
    }

    @Override
    public Object next() {
        if ( currentIndex == collection.size() - 1 ) {
            return null;
        }
        return collection.get(currentIndex ++);
    }

    @Override
    public boolean hasNext() {
        if( currentIndex == collection.size() - 1 ) {
            return false;
        }else{
            return true;
        }
    }

    private Collection collection = null;
    private int currentIndex = 0;
}

public interface Collection {
    public Iterator iterator();
    public Object get(int index);
    public int size();
}

public class ConcreteCollection implements Collection {
    public String[] stringBuffer = {"A", "B", "C", "D", "E"};

    @Override
    public Iterator iterator() {
        return new ConcreteIterator(this);
    }

    @Override
    public Object get(int index) {
        return stringBuffer[index];
    }

    @Override
    public int size() {
        return stringBuffer.length;
    }
}
Chain of Responsibility Pattern
Motivation

In writing an application of any kind, it often happens that the event generated by one object needs to be handled by another one. And, to make our work even harder, we also happen to be denied access to the object which needs to handle the event. In this case, there are two possibilities: there is the beginner/lazy approach of making everything public, creating references to every object, and continuing from there and then there is the expert approach of using the Chain of Responsibility.

The Chain of Responsibility design pattern allows an object to send a command without knowing what object will receive and handle it. The request is sent from one object to another making them parts of a chain and each object in this chain can handle the command, pass it on or do both. The most usual example of a machine using the Chain of Responsibility is the vending machine coin slot: rather than having a slot for each type of coin, the machine has only one slot for all of them. The dropped coin is routed to the appropriate storage place that is determined by the receiver of the command.

Indent
  • It avoids attaching the sender of a request to its receiver, giving this way other objects the possibility of handling the request too.
  • The objects become parts of a chain and the request is sent from one object to another across the chain until one of the objects will handle it.
Implementation

Example
public abstract class Handler {
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public abstract void handleRequest(Request request);

    protected Handler successor;
}

public class ConcreteHandlerA extends Handler {
    @Override
    public void handleRequest(Request request) {
        System.out.println("ConcreteHandlerA handled the request.")
    }
}

public class ConcreteHandlerB extends Handler {
    @Override
    public void handleRequest(Request request) {
        System.out.println("ConcreteHandlerB handled the request.")
    }
}

public class ConcreteHandlerC extends Handler {
    @Override
    public void handleRequest(Request request) {
        System.out.println("ConcreteHandlerC handled the request.")
    }
}

public class HandlerTest {
    public static void main(String[] args) {
        Handler h1 = new ConcreteHandlerA();
        Handler h2 = new ConcreteHandlerB();
        Handler h3 = new ConcreteHandlerC();
        h1.setSuccessor(h2);
        h2.setSuccessor(h3);

        h1.handleRequest(new Request());
    }
}

The expected output:

ConcreteHandlerA handled the request.
ConcreteHandlerB handled the request.
ConcreteHandlerC handled the request.
Command Pattern
Motivation

“An object that contains a symbol, name or key that represents a list of commands, actions or keystrokes”. This is the definition of a macro, one that should be familiar to any computer user. From this idea the Command design pattern was given birth.
The Macro represents, to some extent, a command that is built from the reunion of a set of other commands, in a given order. Just as a macro, the Command design pattern encapsulates commands (method calls) in objects allowing us to issue requests without knowing the requested operation or the requesting object. The command design pattern provides the options to queue commands, undo/redo actions, and other manipulations.

Indent
  • encapsulate a request in an object
  • allows the parameterization of clients with different requests
  • allows saving the requests in a queue
Implementation

Example

Memento Pattern
Motivation

It is sometimes necessary to capture the internal state of an object at some point and have the ability to restore the object to that state later in time. Such a case is useful in case of error or failure. Consider the case of a calculator object with an undo operation such a calculator could simply maintain a list of all previous operations that it has performed and thus would be able to restore a previous calculation it has performed. This would cause the calculator object to become larger, more complex, and heavyweight, as the calculator object would have to provide additional undo functionality and should maintain a list of all previous operations. This functionality can be moved out of the calculator class so that an external (let’s call it to undo manager class) can collect the internal state of the calculator and save it. However, providing explicit access to every state variable of the calculator to the restore manager would be impractical and would violate the encapsulation principle.

Indent
  • The intent of this pattern is to capture the internal state of an object without violating encapsulation and thus provide a mean for restoring the object to its initial state when needed.
Implementation

Example
public class Originator {
    public Originator(State state) {
        this.state = state;
    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    public Memento createMemento(){
        return new Memento(state);
    }

    public void restoreMemento(Memento memento){
        this.state = memento.getState();
    }

    private State state;
}

public class Memento {
    public Memento(State state) {
        this.state = state;
    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    private State state;
}

public class CareTaker {
    public CareTaker(Memento memento) {
        this.memento = memento;
    }

    public Memento getMemento() {
        return memento;
    }

    public void setMemento(Memento memento) {
        this.memento = memento;
    }

    private Memento memento;
}

public class MementoTest {
    public static void main(String[] args) {
        Originator originator = new Original(new State("State A"));
        CareTaker careTaker = new CareTaker(originator.createMemento());

        originator.setState("State B");
        originator.restoreMemento(careTaker.getMemento());
    }
}
Null Object Pattern(State Pattern)
Motivation

There are some cases when a system has to use some functionality and some cases when it doesn’t. Let’s say we have to implement a class that should send the results to a log file or to the console. But this is just an additional option and the data is logged depending on the configuration values.

If there are cases when the client module does not have to log any data then it has to check the configuration parameter in and if block and then call or not the Logger class. But as we know the ‘if’ block is not an elegant solution.

Indent
  • Provide an object as a surrogate for the lack of an object of a given type.
  • The Null Object Pattern provides intelligent do nothing behavior, hiding the details from its collaborators.
Implementation

Example

Log System

Let’s say we need a logging framework in order to support the logging of an application. The framework must fulfill the following requirements:

  • The destination of the output messages should be selected from a configuration file and it can be one of the following options: Log File, Standard Console, or Log Disabled.
  • Must be open for extension; a new logging mechanism can be added without touching the existing code.
Visitor Pattern
Motivation

Collections are data types widely used in object-oriented programming. Often collections contain objects of different types and in those cases, some operations have to be performed on all the collection elements without knowing the type.

A possible approach to applying a specific operation on objects of different types in a collection would be the use of blocks in conjunction with ‘instanceof’ for each element. This approach is not a nice one, not flexible, and not object-oriented at all. At this point, we should think about the Open Close Principle and we should remember from there that we can replace blocks with an abstract class, and each concrete class will implement its own operation.

Indent
  • Represents an operation to be performed on the elements of an object structure.
  • Visitor lets you define a new operation without changing the classes of the elements on which it operates.
Implementation

Example
public interface Visitor {
    public void visit(Subject sub);
}

public class ConcreteVisitor implements Visitor {
    @Override
    public void visit(Element element) {
        System.out.println("Visit the element: "+ element.getElement());
    }
}

public interface Element {
    public void accept(Visitor visitor);
    public String getElement();
}

public class ConcreteElement implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    @Override
    public String getElement() {
        return "ConcreteElement";
    }
}
Mediator Pattern
Motivation

In order to have a good object-oriented design, we have to create lots of classes interacting with each other. If certain principles are not applied the final framework will end in a total mess where each object relies on many other objects in order to run. In order to avoid tightly coupled frameworks, we need a mechanism to facilitate the interaction between objects in a manner in which objects are not aware of the existence of other objects.

Let’s take the example of a screen. When we create it we add all sorts of controls to the screen. This control needs to interact with all the other control. For example, when a button is pressed it must know if the data is valid in other controls. As you have seen if you created different applications using forms you don’t have to modify each control class each time you add a new control to the form. All the operations between controls are managed by the form class itself. This class is called a mediator.

Indent
  • 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.
Implementation

Example
public interface Mediator {
    public void createMediator();
    public void doWork();
}

public class ConcreteMediator implements Mediator {
    public User getColleagueA() {
        return colleagueA;
    }

    public User getColleagueB() {
        return colleagueB;
    }

    @Override
    public void createMediator() {
        colleagueA = new ColleagueA(this);
        colleagueB = new ColleagueB(this);
    }

    @Override
    public void doWork() {
        colleagueA.work();
        colleagueB.work();
    }

    private Colleague colleagueA;
    private Colleague colleagueB;
}

public abstract class Colleague {
    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }

    public Mediator getMediator() {
        return mediator;
    }

    public abstract void work();

    private Mediator mediator;
}

public class ColleagueA extends Colleague {
    public ColleagueA(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void work() {
        System.out.println("ColleagueA is working.");
    }
}

public class ColleagueB extends Colleague {
    public ColleagueB(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void work() {
        System.out.println("ColleagueB is working.");
    }
}

public class MediatorTest {
    public static void main(String[] args) {
        Mediator mediator = new ConcreteMediator();
        mediator.createMediator();
        mediator.doWork();
    }
}
Interpreter Pattern
Motivation

The Interpreter is one of the Design Patterns published in the GoF which is not really used. Usually, the Interpreter Pattern is described in terms of formal grammar like it was described in the original form in the GoF but the area where this design pattern can be applied can be extended.

Indent
  • Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
  • Map a domain to a language, the language to a grammar, and the grammar to a hierarchical object-oriented design
Implementation

Example
public interface Expression {
    public int interpret(Context context);
}

public class Plus implements Expression {
    @Override
    public int interpret(Context context) {
        return context.getNum1() + context.getNum2();
    }
}

public class Minus implements Expression {
    @Override
    public int interpret(Context context) {
        return context.getNum1() - context.getNum2();
    }
}

public class Context {
    public Context(int num1, int num2) {
        this.num1 = num1;
        this.num2 = num2;
    }

    public int getNum1() {
        return num1;
    }

    public void setNum1(int num1) {
        this.num1 = num1;
    }

    public int getNum2() {
        return num2;
    }

    public void setNum2(int num2) {
        this.num2 = num2;
    }

    private int num1;
    private int num2;
}

public class InterpreterTest {
    public static void main(String[] args) {
        int result = new Minus().interpret((new Context(new Plus()
                .interpret(new Context(9, 2)), 8)));
        System.out.println(result);
    }
}

References

The Disqus comment system is loading ...
If the message does not appear, please check your Disqus configuration.