Decorator Pattern

Decorator Pattern

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

Environment

  • Programming Language: Java

Index

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

How to Use (Example)

  • Decorated Class
    public abstract class Beverage {
        protected String description = "Unknown Beverage";
    
        public String getDescription() {
            return description;
        }
    
        public abstract double cost();
    }
    
    public class Espresso extends Beverage {
        public Espresso() {
            description = "Espresso";
        }
    
        public double cost() {
            return 1.99;
        }
    }
    
  • Decorator Class
    public abstract class CondimentDecorator extends Beverage {
        protected Beverage beverage;
    
        public abstract String getDescription();
    }
    
    public class Mocha extends CondimentDecorator {
        public Mocha(Beverage beverage) {
            this.beverage = beverage;
        }
    
        public String getDescription() {
            return beverage.getDescription() + ", Mocha";
        }
    
        public double cost() {
            return 0.2 + beverage.cost();
        }
    }
    
    public class Whip extends CondimentDecorator {
        public Mocha(Beverage beverage) {
            this.beverage = beverage;
        }
    
        public String getDescription() {
            return beverage.getDescription() + ", Whip";
        }
    
        public double cost() {
            return 0.3 + beverage.cost();
        }
    }
    
  • Main
    public class Main {
        public static void main(String args[]) {
            Beverage beverage = new Espresso();
            beverage = new Mocha(beverage);
            beverage = new Mocha(beverage);
            beverage = new Whip(beverage);
            System.out.println(beverage.getDescription() + " $" + beverage.cost());
        }
    }
    




Comments