[디자인패턴]6.데코레이터패턴

송송승현's avatar
Nov 13, 2024
[디자인패턴]6.데코레이터패턴
 

정의

💡
객체에 동적으로 새로운 기능을 추가할 수 있게 해주는 구조적 디자인 패턴.
상속을 통해서 기능을 확장하는 것보다 더 유연해 질 수 있음
데코레이터 패턴은 주로 기존 클래스의 코드를 수정하지 않고도 추가적인 기능을 제공하고 싶을 때 사용

예제

public interface Notifier { void send(); } public class BasicNotifier implements Notifier{ Notifier notifier; public BasicNotifier() { } public BasicNotifier(Notifier notifier) { this.notifier = notifier; } public void send(){ if ( notifier != null){ notifier.send(); } System.out.println("기본 알림"); } } public class EmailNotifier implements Notifier{ Notifier notifier; public EmailNotifier() { } public EmailNotifier(Notifier notifier) { this.notifier = notifier; } @Override public void send(){ if(notifier != null){ notifier.send(); } System.out.println("이메일 알림"); } } public class SmsNotifier implements Notifier{ Notifier notifier; public SmsNotifier() { } public SmsNotifier(Notifier notifier) { this.notifier = notifier; } @Override public void send() { if(notifier != null) { notifier.send(); } System.out.println("SMS 알림"); } } public class App { public static void 알림(Notifier notifier){ notifier.send(); } // 데코레이터 패턴 -> 기능 확장 public static void main(String[] args) { // 1. 전체 알림(기본 알림 -> 문자 알림 -> 이메일 알림) Notifier notifier = new BasicNotifier(new SmsNotifier(new EmailNotifier())); 알림(notifier); // 2. 전체 알림(기본 알림 -> 이메일 알림 -> 문자 알림) Notifier notifier2 = new BasicNotifier(new EmailNotifier(new SmsNotifier())); 알림(notifier2); // 3. 기본 알림 Notifier notifier3 = new BasicNotifier(); 알림(notifier3); // 4. 기본 알림 - 문자 알림 Notifier notifier4 = new BasicNotifier(new SmsNotifier()); 알림(notifier4); // 5. 기본 알림 - 이메일 알림 Notifier notifier5 = new BasicNotifier(new EmailNotifier()); 알림(notifier5); // 6. 이메일 알림 Notifier notifier6 = new EmailNotifier(); 알림(notifier6); // 7. 문자 알림 Notifier notifier7 = new SmsNotifier(); 알림(notifier7); // 8. 문자 알림 - 이메일 알림 Notifier notifier8 = new SmsNotifier(new EmailNotifier()); 알림(notifier8); } }

구성

  • 컴포넌트(Component): 데코레이터와 구체적인 객체가 구현해야 하는 공통 인터페이스 또는 추상 클래스
  • 구체적인 컴포넌트(ConcreteComponent): 기본 기능을 구현하는 클래스
  • 데코레이터(Decorator): 컴포넌트 인터페이스를 구현하며, 구체적인 컴포넌트를 포함하여 추가 기능을 제공하는 추상 클래스
  • 구체적인 데코레이터(ConcreteDecorator): 데코레이터 클래스의 구체적인 구현으로, 추가 기능을 제공
 

장점

  • 유연한 기능 확장 : 기존 코드를 수정하지 않고도 객체에 새로운 기능을 추가 할 수 있음
  • 단일 책임 원칙 준수 : 클래스의 책임을 분리할 수 있음. 각각의 데코레이터는 추가적인 기능만을 담당하여 클래스가 하나의 책임만 가질 수 있음
  • 객체 합성 : 객체 합성을 사용하여 기능을 확장. 컴파일 시에 상속 구조를 결정하는 것보다 런타임에 동적으로 기능을 결합하는 것을 가능
  • 유지보수 용이 : 새로운 기능을 추가하거나 기존 기능을 변경할 때, 데코레이터만 수정하면 되므로 유지보수가 용이

단점

  • 복잡성 증가 : 클래스 수가 증가하여 코드가 복잡해짐
  • 디버깅 어려움 : 데코레이터가 여러 겹으로 쌓일 경우, 디버깅이 어려움
  • 런타임 비용 : 직접적인 호출보다 런타임 비용이 약간 증가
  • 객체 식별 문제 : 데코레이터가 감싸고 있는 객체를 식별하기 어려움. 특정 객체를 직접 접근할 때 문제가 생길 수 있음
 
Share article

송승현의 블로그