노현진's Blog

Decorator Pattern

Decorator Pattern에 대해 설명하는 페이지입니다.

Posted
Preview Image
By HyunJinNo

Tags

Design Pattern, Java

1. Introduction

  • Purpose
    • Allows for the dynamic wrapping of objects in order to modify their existing responsibilities and behaviors.
  • Use When
    • Object responsibilities and behaviors should be dynamically modifiable.
    • Concrete implementions should be decoupled from responsibilities and behaviors.
    • Subclassing to achieve modification is impratical or impossible.
    • Specific functionality should not reside high in the object hierarchy.
    • A lot of little objects surrounding a concrete implementation is acceptable.
  • Characteristics
    • We can use one or more decorators to wrap an object.
    • Decorators have the same super type as the objects they decorate.
    • We can decorate objects dynamically at runtime with as many decorators as we want.
  • Design Principle
    • Open-Closed Principle (OCP)
  • Mechanisms
    • Uses object composition and delegation
    • Decorator class mirrors the type of components they are decorating.
      • We can wrap a component with any number of decorators
  • Advantages
    • attaches additional responsibilities to an object dynamically
    • flexible alternative to subclassing for extending functionality
  • Disadvantages
    • can generate a lot of small classes (ex. Java I/O)
    • hard to understand if not familiar with the pattern

2. How to Use (Example)

  • Decorated Class

    java
    1public abstract class Beverage {
    2    protected String description = "Unknown Beverage";
    3
    4    public String getDescription() {
    5        return description;
    6    }
    7
    8    public abstract double cost();
    9}
    10
    11public class Espresso extends Beverage {
    12    public Espresso() {
    13        description = "Espresso";
    14    }
    15
    16    public double cost() {
    17        return 1.99;
    18    }
    19}
  • Decorator Class

    java
    1public abstract class CondimentDecorator extends Beverage {
    2    protected Beverage beverage;
    3
    4    public abstract String getDescription();
    5}
    6
    7public class Mocha extends CondimentDecorator {
    8    public Mocha(Beverage beverage) {
    9        this.beverage = beverage;
    10    }
    11
    12    public String getDescription() {
    13        return beverage.getDescription() + ", Mocha";
    14    }
    15
    16    public double cost() {
    17        return 0.2 + beverage.cost();
    18    }
    19}
    20
    21public class Whip extends CondimentDecorator {
    22    public Mocha(Beverage beverage) {
    23        this.beverage = beverage;
    24    }
    25
    26    public String getDescription() {
    27        return beverage.getDescription() + ", Whip";
    28    }
    29
    30    public double cost() {
    31        return 0.3 + beverage.cost();
    32    }
    33}
  • Main

    java
    1public class Main {
    2    public static void main(String args[]) {
    3        Beverage beverage = new Espresso();
    4        beverage = new Mocha(beverage);
    5        beverage = new Mocha(beverage);
    6        beverage = new Whip(beverage);
    7        System.out.println(beverage.getDescription() + " $" + beverage.cost());
    8    }
    9}

© HyunJinNo. Some rights reserved.