Decorator

Definition


Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

UML class diagram


Participants


  • Component
    • defines the interface for objects that can have responsibilities added to them dynamically.
  • ConcreteComponent
    • defines an object to which additional responsibilities can be attached.
  • Decorator
    • maintains a reference to a Component object and defines an interface that conforms to Component's interface.
  • ConcreteDecorator
    • adds responsibilities to the component.

Sample code in Java

package com.hong.decorator;

interface Component{
    public void operation();
}

class ConcreteComponent implements Component
{
    private String name; 
    
    public ConcreteComponent(String name){
        this.name = name;
    }
    
    @Override 
    public void operation(){
        
        System.out.println("operation from ConcreteComponent " + this.name);
    }
}

class Decorator implements Component
{
    protected Component component; 
    protected String name;
    public Decorator(Component component, String name)
    {
        this.component = component;
        this.name = name;
    }
    
    @Override
    public void operation()
    {
        if(null != component)
            component.operation();
    }
}

class ConcreteDecoratorA extends Decorator
{
    
    public ConcreteDecoratorA(Component component, String name) {
        super(component, name);
    }
    @Override
    public void operation(){
        
        super.operation(); 
        System.out.println("Additional state from ConcreteDecoratorA " + this.name);
    }
}

class ConcreteDecoratorB extends Decorator{

    public ConcreteDecoratorB(Component component, String name) {
        super(component, name);
    }
    
    @Override
    public void operation(){
        super.operation();
        addedBehavior();
    }
    
    public void addedBehavior(){    
        System.out.println("AddedBehavior from ConcreteComponentB " + this.name);
    }
    
}
public class Decorator_structure {

    public static void main(String[] args){
        
        Decorator borrowable_book = new ConcreteDecoratorA(new ConcreteComponent("book"), "borrawable");
        System.out.println("Display borrawable book:");
        borrowable_book.operation();
        
        System.out.println();
        Decorator discounted_borrowable_book = new ConcreteDecoratorB(borrowable_book, "discounted");
        System.out.println("Display discounted_borrowable book:"); 
        discounted_borrowable_book.operation();
        
    }
}