inblog logo
|
jay0628
    디자인 패턴

    [디자인 패턴] 7. Decorator 패턴

    김주희's avatar
    김주희
    Jul 24, 2025
    [디자인 패턴] 7. Decorator 패턴
    Contents
    예제 - 알림 보내기
    notion image
     
     
    책임 분리하고 ~하고 나서 패턴 적용 (SOLID가 적용되고 난 뒤에 패턴을 적용한다 = 전략 패턴을 지키고 나서 패턴 적용한다)
     
    데코레이터 패턴의 목적은 기능의 확장이다.
    그럼 상속 아닌가? 라는 생각이 들 수 있다.
     
     

    예제 - 알림 보내기

    1단계

    DIP고 OCP고 뭐고 생각하고 설계하고 만들지 말자. 처음에는 일단 만들어야 한다.
    notion image
    notion image
     
    이메일 알림 클래스는 팀원이 만들었다고 가정하자. 즉 나는 아래의 코드를 모르고 있는 상황이다.
    notion image
     
    이메일 알림을 쓰려고 하니까 send가 없네? 지금은 툴이 있으니까 알 수 있지만 이전에는 모르거나 send라는 일관성이 없다.
     
    강제성을 주기 위해 추상 메서드를 사용한다. 이때 인터페이스든 추상 클래스든 상관 없다. 따라서 추상 메서드를 쓰게 되면 강제성이 부여되는 것 뿐만 아니라 추상화까지 적용된다.
    notion image
     
    notion image
    notion image
    notion image
     
     
    notion image
    notion image
     
     

    2단계 : email 알림과 기본 알림을 같이 보내고 싶어!

    notion image
    notion image
    notion image
     
     
    ⇒ 2번 호출이 아니라 한 번의 호출로 이메일과 기본 알림 둘 다 보낼 수 있도록 해주는게 데코레이터 패턴!
     

    3단계 : 데코레이터 패턴을 적용해보자

    notifier가 notifier를 has해서 재귀적으로 해결 가능하다.

    1. 이메일 알림

    notion image
     
    notion image
    notion image
     
    null 넣는거 불편ㅠ → 기본 생성자를 만들자
    notion image
    notion image
     

    2. 기본 + 이메일, 문자 + 이메일

    notion image
     

    3. 문자 알림 + 이메일 알림 + 기본 알림

    기본 알림에는 없는게 좋음 끝이 잇어야 하니께..
    notion image
     

    4. 문자 알림 + 문자 알림 + 이메일 알림 + 기본 알림

    notion image
     

    5. 이제 저 선택 값들을 가지고 어떻게 객체를 만들지?

    1. for문 돌리기
    1. reflection
    { "userId" : 5, "notiTypeList" : ["sms", "sms", "email", "basic"] }
    notion image
    notion image
     
     

    그래서 reflection을 적용한다면?

    package ex06; import ex06.notification.Notifier; import java.util.List; public class App { public static void main(String[] args) throws Exception { List<String> notiTypeList = List.of("sms", "sms", "email", "basic"); Notifier chain = NotifierFactory.buildNotifierChain(notiTypeList); ClientNotification.send(chain); } }
     
    package ex06; import ex06.notification.Notifier; import java.util.List; public class NotifierFactory { public static Notifier buildNotifierChain(List<String> typeList) throws Exception { Notifier chain = null; for (int i = typeList.size() - 1; i >= 0; i--) { String type = typeList.get(i); String className = "ex06.notification." + capitalize(type) + "Notifier"; Class<?> clazz = Class.forName(className); if (chain == null) { chain = (Notifier) clazz.getDeclaredConstructor().newInstance(); } else { chain = (Notifier) clazz.getDeclaredConstructor(Notifier.class).newInstance(chain); } } return chain; } private static String capitalize(String str) { return str.substring(0, 1).toUpperCase() + str.substring(1); } }
     
    구조
    App → 프로그램 실행 시작 └─> NotifierFactory → 알림 체인을 생성 └─> ClientNotification.send() → 알림 전송
     
    Reflection 구현
    Share article

    jay0628

    RSS·Powered by Inblog