程序员

Decorator Pattern

2016-04-12  本文已影响40人  Hackjutsu

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

Intent

Implementation

Class Diagram of Decorator Pattern

Below is an interface depicting an icecream

// Icecream.java
public interface Icecream {
    public String makeIcecream();
}

This is the base class on which the decorators will be added.

// SimpleIcecream.java
public class SimpleIcecream implements Icecream {

    @Override
    public String makeIcecream() {
        return "Base Icecream";
    }
}

Following class is the decorator class. It is the core of the decorator design pattern. It contains an attribute for the type of interface. Instance is assigned dynamically at the creation of decorator using its constructor. Once assigned that instance method will be invoked.

// IcecreamDecorator.java
abstract class IcecreamDecorator implements Icecream {

    protected Icecream specialIcecream;

    public IcecreamDecorator(Icecream specialIcecream) {
        this.specialIcecream = specialIcecream;
    }

    public String makeIcecream() {
        return specialIcecream.makeIcecream();
    }
}

These are two decorators, concrete class implementing the abstract decorator. When the decorator is created the base instance is passed using the constructor and is assigned to the super class.

// NuttyDecorator.java
public class NuttyDecorator extends IcecreamDecorator {

    public NuttyDecorator(Icecream specialIcecream) {
        super(specialIcecream);
    }

    public String makeIcecream() {
        return specialIcecream.makeIcecream() + addNuts();
    }

    private String addNuts() {
        return " + cruncy nuts";
    }
}
// HoneyDecorator.java
public class HoneyDecorator extends IcecreamDecorator {

    public HoneyDecorator(Icecream specialIcecream) {
        super(specialIcecream);
    }

    public String makeIcecream() {
        return specialIcecream.makeIcecream() + addHoney();
    }

    private String addHoney() {
        return " + sweet honey";
    }
}

Execution of the decorator pattern
We can use as many decorators in any order we want. This excellent flexibility and changing the behaviour of an instance of our choice at runtime is the main advantage of the decorator design pattern.

// TestDecorator.java
public class TestDecorator {

    public static void main(String args[]) {
        Icecream icecream = new HoneyDecorator(new NuttyDecorator(new SimpleIcecream()));
        System.out.println(icecream.makeIcecream());
    }
}

Output

Base Icecream + cruncy nuts + sweet honey

Decorator Pattern in Java API

The java.io classes are based on Decorator.

Head First Design Pattern ---- Decorator Pattern

This example also points out one of the downsides of the Decorator Pattern: designs often result in a large number of small classes that can be overwhelming.

Reference

JavaPapers
Hackjustu Dojo (my blog)

上一篇下一篇

猜你喜欢

热点阅读