데코레이터 패턴

홍준식·2024년 6월 16일
post-thumbnail

객체의 결합을 통해 동적으로 새로운 기능을 추가하는 패턴

예를 들어, 특정 객체가 실행되면 알림을 줘야하는 경우가 있다고 하자.
이메일 알림, 슬랙 알림, 메세지 알림이 존재한다면 어떤 객체는 이메일 알림만을, 어떤 객체는 이메일 알림과 슬랙 알림을 모두 보내야 할 것이다.
즉, 3가지 동작을 혼합한 8가지 함수를 만들어야하고 이를 해결하기 위해 데코레이터 패턴을 사용한다.

컴포넌트는 모든 객체의 공통 인터페이스를 선언한다.
Concrete Component는 기본 행동을 정의하고 데코레이터는 이 기본행동에 추가 행동을 더한다.
기초 데코레이터는 클래스에 래핑된 객체를 참조하기 위한 컴퓨넌트 인터페이스 타입의 필드를 가지고 있다.
구상 데코레이터는 컴퓨넌트에 동적으로 추가될 수 있는 행동들을 정의한다.

예제

from abc import ABC, abstractmethod

# Component
class Notifier(ABC):
    @abstractmethod
    def send(self, message: str):
        pass

# ConcreteComponent
class BasicNotifier(Notifier):
    def send(self, message: str):
        print(f"Basic Notification: {message}")

# Base Decorator
class NotifierDecorator(Notifier):
    def __init__(self, notifier: Notifier):
        self._notifier = notifier

    def send(self, message: str):
        self._notifier.send(message)

# ConcreteDecorator
class SlackNotifier(NotifierDecorator):
    def send(self, message: str):
        super().send(message)
        self.send_slack_notification(message)

    def send_slack_notification(self, message: str):
        print(f"Sending Slack notification: {message}")

class EmailNotifier(NotifierDecorator):
    def send(self, message: str):
        super().send(message)
        self.send_email_notification(message)

    def send_email_notification(self, message: str):
        print(f"Sending Email notification: {message}")

class MessageNotifier(NotifierDecorator):
    def send(self, message: str):
        super().send(message)
        self.send_message_notification(message)

    def send_message_notification(self, message: str):
        print(f"Sending Message notification: {message}")

# Client code
if __name__ == "__main__":
    # 기본 알림
    notifier = BasicNotifier()
    notifier.send("Hello, this is a basic notification!")

    print("\nAdding Slack Notification:")
    # 슬랙 알림 추가
    slack_notifier = SlackNotifier(notifier)
    slack_notifier.send("Hello, this is a slack notification!")

    print("\nAdding Email Notification:")
    # 이메일 알림 추가
    email_notifier = EmailNotifier(slack_notifier)
    email_notifier.send("Hello, this is an email notification!")

    print("\nAdding Message Notification:")
    # 메시지 알림 추가
    message_notifier = MessageNotifier(email_notifier)
    message_notifier.send("Hello, this is a message notification!")
Basic Notification: Hello, this is a basic notification!

Adding Slack Notification:
Basic Notification: Hello, this is a slack notification!
Sending Slack notification: Hello, this is a slack notification!

Adding Email Notification:
Basic Notification: Hello, this is an email notification!
Sending Slack notification: Hello, this is an email notification!
Sending Email notification: Hello, this is an email notification!

Adding Message Notification:
Basic Notification: Hello, this is a message notification!
Sending Slack notification: Hello, this is a message notification!
Sending Email notification: Hello, this is a message notification!
Sending Message notification: Hello, this is a message notification!

0개의 댓글