PSD( Private-Self-Development )

장식자 패턴 본문

Backend/디자인패턴

장식자 패턴

chjysm 2023. 5. 22. 15:31

장식자 패턴?

객체에 동적으로 기능을 추가하기 위해 구조를 개선하는 디자인 패턴이다.

복합체 패턴과 마찬가지로  동일한 인터페이스를 구현하여 투명성을 가지며

개방/폐쇄의 원칙을 추구한다.

래퍼 패턴으로도 불린다. 

 

기능 추가를 위해서는 상속과 구성 두 가지 방법이 있다.

이 중 상속은  이전에도 기술하였듯이 객체 간 강력한 결합이 수반되기 때문에,

구성으로 기능 추가를 구현하는 것이 좋다. 

 

상속의 문제점 

  • 상속은 정적 
  • 하나의 부모 클래스만 가질 수 있다.
  • 강력한 결합

 

4가지 구성 요소

  • Component : 공통 적용 될 인터페이스 
  • ConcreateComponent : 실 객체 이자 Component 구현체 
  • Decorator : 장식자 인터페이스 
  • ConcreateDecorator : 장식자 인터페이스 구현체 확장 및 추가되는 기능 작성 

 

장식자 패턴의 장점

  • 동적 객체 확장
  • 객체를 여러 장식자로 래핑 하여 합성할 수 있다.
  • 단일 책임 원칙
  • 개방/폐쇄 원칙

 

장식자 패턴의 단점

  • 래퍼들의 스택이 쌓인 경우, 특정 래퍼만 제거가 어렵다
  • 장식자의 행동이 장식자 스택 순서에 의존적이다.
  • 자잘한 클래스로 나뉘어 클래스가 많아진다. => 이는 장점으로도 생각 가능하다.

 

장식자 패턴의 구현

// component : 공통으로 적용되는 인터페이스, 추상 메서드로 선언되어도 된다.
public interface Noti {
    String sendMessage();
}

// concreateComponent
public class KoreaNoti implements Noti {
    @Override
    public String sendMessage() {
        return "안녕하세요";
    }
}

// concreateComponent
public class EnglishNoti implements Noti {
    @Override
    public String sendMessage() {
        return "hello";
    }
}

// Decorator
public abstract class NotiDecorator implements Noti{
    public abstract String sendMessage();
}

// ConcreateDecorator
@AllArgsConstructor
public class SnsNotiDecorator extends NotiDecorator{

    protected Noti base;

    @Override
    public String sendMessage() {
        return base.sendMessage() + " : SNS";
    }
}

// ConcreateDecorator
@AllArgsConstructor
public class FaceBookNotiDecorator extends NotiDecorator{

    protected Noti base;

    @Override
    public String sendMessage() {
        return base.sendMessage() + " : 페이스북";
    }
}

// 사용 예
public static void main(String[] args) {
    KoreaNoti koreaNoti = new KoreaNoti();
    FaceBookNotiDecorator faceBookNotiDecorator = new FaceBookNotiDecorator(koreaNoti);
    SnsNotiDecorator snsNotiDecorator = new SnsNotiDecorator(faceBookNotiDecorator);

    System.out.println(snsNotiDecorator.sendMessage());
}

 

언제 사용해야 할까?

  • 객체에 동적으로 기능을 추가하기 위한 경우
  • 객체를 다양하게 확장하도록 설계하고 싶은 경우 

 


참조

https://refactoring.guru/ko/design-patterns/decorator

'Backend > 디자인패턴' 카테고리의 다른 글

플라이웨이트 패턴  (0) 2023.05.23
파사드 패턴  (0) 2023.05.23
복합체 패턴  (0) 2023.05.19
브리지 패턴  (0) 2023.05.15
디자인 패턴  (0) 2023.05.15