Today we’re going over the decorator pattern. It’s used to add new functionality to existing classes.

package com.jaronoff.decorators;

public interface Burrito {
  public String makeBurrito();
}

package com.jaronoff.decorators;

public class SimpleBurrito implements Burrito {

  @Override
  public String makeBurrito() {
    return "Base Burrito";
  }

}
package com.jaronoff.decorators;

abstract class BurritoDecorator implements Burrito {

  protected Burrito specialBurrito;

  public BurritoDecorator(Burrito specialBurrito) {
    this.specialBurrito = specialBurrito;
  }

  public String makeBurrito() {
    return specialBurrito.makeBurrito();
  }
}
package com.jaronoff.decorators;

public class CheeseDecorator extends BurritoDecorator {

  public CheeseDecorator(Burrito specialBurrito) {
    super(specialBurrito);
  }

  public String makeBurrito() {
    return specialBurrito.makeBurrito() + addCheese();
  }

  private String addCheese() {
    return " + cheese";
  }
}
package com.jaronoff.decorators;

public class BeanDecorator extends BurritoDecorator {

  public BeanDecorator(Burrito specialBurrito) {
    super(specialBurrito);
  }

  public String makeBurrito() {
    return specialBurrito.makeBurrito() + addBeans();
  }

  private String addBeans() {
    return " + black beans";
  }
}
package com.jaronoff.decorators;

public class TestDecorator {

  public static void main(String args[]) {
    Burrito burrito = new BeanDecorator(new CheeseDecorator(new SimpleBurrito()));
    System.out.println(burrito.makeBurrito());
  }

}
Base Burrito + cheese + black beans