[심화] 8. 데코레이터 패턴

백하림's avatar
Jul 25, 2025
[심화] 8. 데코레이터 패턴
notion image

App.java

package ex06; import ex06.notification.BasicNotifier; import ex06.notification.EmailNotifier; import ex06.notification.SmsNotifier; public class App { public static void main(String[] args) { // Notifier b1 = new BasicNotifier(); // b1.send(); // System.out.println("_end"); // // Notifier e1 = new EmailNotifier(); // e1.send(); // System.out.println("_end"); // // Notifier s1 = new SmsNotifier(); // s1.send(); // System.out.println("_end"); // 1. 이메일 알림 EmailNotifier n1 = new EmailNotifier(); n1.send(); System.out.println("_end"); // 2. 이메일 알림 + 기본 알림 EmailNotifier n2 = new EmailNotifier(new BasicNotifier()); n2.send(); System.out.println("_end"); // 3. 이메일 알림 + 문자 알림 EmailNotifier n3 = new EmailNotifier(new SmsNotifier()); n3.send(); System.out.println("_end"); // 4. 문자 알림 + 기본 알림 SmsNotifier n4 = new SmsNotifier(); n4.send(); System.out.println("_end"); // 5. 문자 알림 + 이메일 알림 + 기본 알림 SmsNotifier n5 = new SmsNotifier(new EmailNotifier(new BasicNotifier())); n5.send(); System.out.println("_end"); // 6. 문자 알림 + 문자 알림 + 이메일 알림 + 기본 알림 SmsNotifier n6 = new SmsNotifier(new SmsNotifier(new EmailNotifier(new BasicNotifier()))); ClientNotification.send(n6); } }

Notifier.java

package ex06.notification; public interface Notifier { void send(); }

ClientNotification.java

package ex06; import ex06.notification.Notifier; public class ClientNotification { public static void send(Notifier s1) { s1.send(); } }

SmsNotifier.java

package ex06.notification; public class SmsNotifier implements Notifier { private Notifier notifier; public SmsNotifier() { } public SmsNotifier(Notifier notifier) { this.notifier = notifier; } @Override public void send() { System.out.println("문자 알림"); if (notifier != null) notifier.send(); } }

EmailNotifier.java

package ex06.notification; public class EmailNotifier implements Notifier { private Notifier notifier; public EmailNotifier() { } public EmailNotifier(Notifier notifier) { this.notifier = notifier; } public void send() { System.out.println("이메일 알림"); if (notifier != null) notifier.send(); } }

BasicNotifier.java

package ex06.notification; public class BasicNotifier implements Notifier { public void send() { System.out.println("기본 알림"); } }

1. 패턴 목적

객체를 감싸며 기능을 점진적으로 확장할 수 있는 구조.
상속 대신 **합성(Composition)**과 **위임(Delegation)**을 사용하여 유연하게 기능 추가함.

2. 구성 요소 정리

클래스명
역할
Notifier (인터페이스)
알림을 보내는 공통 타입 정의 (send() 메서드)
BasicNotifier
실제 알림을 보내는 기본 클래스 (기본 알림 출력)
EmailNotifier
이메일 알림 기능을 추가하는 데코레이터
SmsNotifier
문자 알림 기능을 추가하는 데코레이터
ClientNotification
알림 실행용 클라이언트 클래스 (Notifier 타입 받음)
App
알림 객체 조합 후 실행하는 메인 실행 클래스

3. 동작 방식

  • 각 데코레이터는 내부에 Notifier를 포함(합성)하고 있음
  • send() 호출 시 자기 역할을 먼저 수행한 뒤, 내부 객체에 send()위임
public void send() { System.out.println("문자 알림"); // 자기 일 먼저 if (notifier != null) notifier.send(); // 내부 객체 호출 }

정리

🔥
  • Notifier라는 **인터페이스(또는 추상 클래스)**를 만들고
    • → 거기서 send()라는 기능을 정의해둠 (즉, 반드시 구현해야 함)
  • EmailNotifier, SmsNotifier 같은 자식 클래스는
    • Notifierimplements(또는 extends)
    • 따라서 send()를 반드시 구현함
  • 이 자식 클래스들은 생성자에서 Notifier 타입을 매개변수로 받음
    • 즉, 자신과 같은 타입을 속에 들고 있음 (→ 합성, Composition)
  • send()를 실행하면
    • 먼저 자기 역할을 수행 (예: System.out.println("문자 알림"))
    • 그리고 자기가 들고 있는 Notifier의 send()도 호출
  • 이 구조가 계속 중첩되면
    • 겉에서부터 감싸고
    • send() 실행 시에는 겉에서부터 안으로 차례대로 실행됨
  • 그래서 결과적으로
    • 기능을 조립하듯 추가할 수 있고
    • 기존 클래스는 전혀 수정하지 않아도 됨 → OCP 만족
 
Share article

harimmon