Decorator Pattern

Ahyeon, Jung·2024년 2월 4일
0

Decorator Pattern

객체에 동적으로 새로운 책임을 추가하는 패턴
상속을 통해 기능을 확장하는 대신, 객체를 감싸는 방식으로 기능을 추가하거나 변경
기능을 조합하여 새로운 객체를 생성 가능

서브클래스를 만드는 방식으로 행동을 상속받으면, 그 행동은 컴파일할 때 완전히 결정됨. 게다가 모든 서브클래스에서 똑같은 행동을 상속받아야함 => 구성을 통해 객체의 행동을 확장하면 실행 중에 동적으로 행동을 설정가능함

Component 구성 요소

인터페이스나 추상 클래스로 정의된 기본 객체
객체에 동적으로 책임을 추가할 수 있어야 함

ConcreteComponent 구체적인 구성 요소

Component를 구현한 구체적인 클래스
기본 기능을 제공

Decorator 데코레이터

Component와 동일한 인터페이스를 가지면서 내부에 Component를 갖는 클래스
자신의 행위를 수행한 후에 또 다른 Component를 호출하여 작업을 전달

ConcreteDecorator 구체적인 데코레이터

Decorator를 구현한 구체적인 클래스
추가적인 기능을 제공하거나 기존 기능을 수정함

확장성

새로운 기능을 추가하거나 변경하기 쉬움. 상속보다 유연하게 기능을 확장 가능

구성을 통한 재사용

객체를 감싸는 방식을 통해 기능을 조합하여 재사용 가능

자바스크립트에서 이해하기

Component

class Coffee {
  cost() {
    return 5; // 기본 가격
  }
  
  description() {
    return '기본 커피';
  }
}

Decorator

class CoffeeDecorator {
  constructor(coffee) {
    this._coffee = coffee;
  }
  
  cost() {
    return this._coffee.cost();
  }
  
  description() {
    return this._coffee.description();
  }
}

ConcreteComponent

class MilkDecorator extends CoffeeDecorator {
  constructor(coffee) {
    super(coffee);
  }
  
  cost() {
    return super.cost() + 2; // 우유 추가 가격
  }
  
  description() {
    return super.description() + ', 우유 추가';
  }
}
class SugarDecorator extends CoffeeDecorator {
  constructor(coffee) {
    super(coffee);
  }
  
  cost() {
    return super.cost() + 1; // 설탕 추가 가격
  }
  
  description() {
    return super.description() + ', 설탕 추가';
  }
}

실행

// 기본 커피 주문
let simpleCoffee = new Coffee();
console.log(simpleCoffee.description()); // 기본 커피
console.log(simpleCoffee.cost()); // 5

// 우유 추가한 커피 주문
let milkCoffee = new MilkDecorator(simpleCoffee);
console.log(milkCoffee.description()); // 기본 커피, 우유 추가
console.log(milkCoffee.cost()); // 7

// 설탕 추가한 커피 주문
let sugarCoffee = new SugarDecorator(simpleCoffee);
console.log(sugarCoffee.description()); // 기본 커피, 설탕 추가
console.log(sugarCoffee.cost()); // 6

// 우유와 설탕 모두 추가한 커피 주문
let milkAndSugarCoffee = new SugarDecorator(new MilkDecorator(simpleCoffee));
console.log(milkAndSugarCoffee.description()); // 기본 커피, 우유 추가, 설탕 추가
console.log(milkAndSugarCoffee.cost()); // 8

OCP(Open-Closed Principle)

클래스는 확장에는 열려 있어야 하지만 변경에는 닫혀있어야한다는 디자인 원칙

profile
https://a-honey.tistory.com/

0개의 댓글