소프트웨어 개발자/디자인패턴

[디자인 패턴] 구조 패턴 - 데코레이터 패턴

yubi5050 2024. 6. 8. 17:29

구조 (Structure) 패턴

구조 패턴 이란 객체 간의 상호 작용에 대한 구조적 관계를 명확히 정의하여, 코드의 유연성과 재사용성을 높이는 디자인 패턴

 

주요 패턴으론 다음 사항들이 있다.

  • 어댑터 (Adapter) 
  • 데코레이터(Decorator) <- 이번 글에서 다룰 내용
  • 복합자(Composite)
  • 파셔드(Facade)
  • 플라이웨잇(Flyweight)
  • 프록시(Proxy)
  • 브릿지(Bridge)

 

데코레이터 (Decorator) 패턴 이란

특정 행동을 수행하는 특수 warpper 객체들을, 메인 객체에 연결시키는 구조적 디자인 패턴

 

아래 예시 처럼 wrapping을 점진적으로 진행 하여 대상을 확장함 (상속 대신 데코레이터 패턴으로 행동을 확장 가능)

 

https://refactoring.guru/images/patterns/content/decorator/decorator-2x.png

 

등장 배경

 3가지 종류의 알림을 구현하고자 함.

https://refactoring.guru/images/patterns/diagrams/decorator/problem2-2x.png

 

 

시간이 지날 수록 다양한 조합의 알림 조합 니즈가 생김 -> 이를 패턴화 하여 효율적 으로 만들고자 함

 

https://refactoring.guru/images/patterns/diagrams/decorator/problem3-2x.png

 

구조 

 

1. Client : 데코레이터들이 컴포넌트를 통해, 래핑하는 객체를 여러 계층의 데코레이터를 통해 확장 하는 main

2. 기본 Component : 메인 로직의 래핑 될 객체

3. 기초 데코레이터 (Base Decorator) : 래핑 할 Component 객체에 대한 참조 필드를 가지며, execute()를 통해 점진적 확장 및 역할 수행 

 

https://refactoring.guru/images/patterns/diagrams/decorator/structure-2x.png

 

Python 데코레이터 vs 데코레이터 디자인 패턴

파이썬에서는 decorator 라는 유사한 개념이 있다.

둘 간의 개념과 역할은 유사하지만, 사용방식이나, 적용 하는 대상, 구현 방식 등에서의 차이가 있다. 

특징 파이썬 데코레이터 (Decorator) 데코레이터 패턴 (Decorator Pattern)
적용 대상 함수 또는 메서드 클래스 또는 객체
사용 방식 @ 문법을 사용하여 함수 위에 적용 객체를 감싸는 클래스를 정의하여 사용
주 사용
목적
함수의 동작을 확장하거나 수정 객체의 동작을 동적으로 확장
구현 방식 함수를 인수로 받아서 다른 함수를 반환하는 고차 함수 컴포지션을 사용하여 기능을 동적으로 추가하는 디자인 패턴
주 사용
예시
로깅, 권한 검사, 성능 측정 등의 부가 기능 추가 UI 컴포넌트, 데이터 처리 객체, 다양한 기능 조합 가능

 

 

장단점

장점

  • 서브클래싱 없이 확장이 가능
  • 런타임에 추가/제거가 가능
  • 여러 데코레이터들을 조합하여 여러 행동을 조합 가능
  • SRP. 다양한 가능한 종류의 행동을 가진 하나의 클래스를 여러개의 작은 클래스로 나눌 수 있음

 

단점

  • wrapper stack에서 특정 wrapper 제거하기가 힘듦
  • decorator stack에 의존하지 않는 행동을 가진 데코레이터를 정의하기 힘듦
  • 레이어 초기 구성 코드가 지저분

 

다른 패턴과의 관계

vs (구조 패턴) 어댑터,프록시

  • Adapter : 기존 개체에 액세스하기 위해 완전히 새로운(다른) 인터페이스를 제공
  • Decorator : 인터페이스를 동일하게 유지되거나 확장간 재귀적 조합 가능
  • Proxy : Proxy를 사용하면 인터페이스가 동일하게 유지

 

vs (구조 패턴) Chain of Responsibility (책임 연쇄)

  • 두 패턴 모두 재귀 방식을 이용해, 객체를 조합하여 해당 객체에 실행 책임을 넘김 
  • 책임 연쇄 : 각각 독립적으로 실행 및 특정 구간에서 요청을 멈추기 가능
  • 데코레이터 : 객체의 행동을 확장한다. 게다가, 데코레이터는 요청을 정의한 대로 끝까지 진행

 

vs (구조 패턴) Composite 

  • (공통) 둘 다 재귀적 구성을 사용 (유사한 다이어그램 구조)
  • (공통) 무제한의 개체 수를 구성 할 수 있음.
  • (차이점) Decorator : 하위 구성 요소가 하나만 있고, 해당 래핑된 객체에 추가 책임을 부여 가능
  • (차이점) Composite : Composite는 하위 항목들의 정보를 단순 가지고 있거나, 조합 하는 것

 

vs (행동 패턴) Strategy 

  • 데코레이터 : 객체의 겉을 변경(확장)
  • 전략 패턴 : 객체의 중심을 변경

 

vs 데코레이터, 어댑터, 퍼사드

  • 어댑터 : 하나의 인터페이스를 다른 인터페이스로 변환
  • 데코레이터 : 인터페이스는 바꾸지 않고, 책임(기능)만 추가
  • 퍼사드 : 인터페이스를 보다 간단하게 변경