nono blog
楽しい人生を送りたい!
ITスキル

pythonプログラム デザインパターン(decorator)

構造に関するデーザインパターンの一つであるdecoratorパターン

Decoratorパターンとは

デコレーション:飾り付けのこと
別クラスの持っている特定の機能を、また別のクラスに追加するデザインパターン。
互いに関連したクラスの処理を、クラスを跨いで追加したい場合に用いられる。

通知クラス → Facebook通知クラス
  → Twitter通知クラス
  → Facebook + Twitter 通知クラス

(目的)
複数の機能を一つのクラスにまとめる

(仕組み)
Componetを継承したConcreteComponet, Decoratorを作成する。
Decoratorは、Componentをプロパティに持つ。
Decorratorを継承したConcreteDecoratorを作成する。
利用する際にプロパティにConcreteComponentを設定する。

(構成要素)
Component     : 機能を追加する際の中核となるクラス
ConcreteComponent : 追加する処理を記載したComponentを継承したクラス
Decorator     : Componentを継承したクラスで、プロパティにComponentを持つ
ConcreteDecorator : Decorator を処理を具体的に記述したクラス

サンプルプログラム

pythonによるサンプルプログラム

# decorator.py
from abc import ABC, abstractmethod


class Component(ABC):

    @abstractmethod
    def operation(self):
        pass


class ShowCharComponent(Component):

    def __init__(self, char):
        self.__char = char

    def operation(self):
        print(self.__char * 20)


class ShowDecorator(Component):

    def __init__(self, componet: Component):
        self._component = componet


class ShowMessage(ShowDecorator):

    def __init__(self, componet: Component, msg):
        super().__init__(componet)
        self.__msg = msg

    def operation(self):
        self._component.operation() # Component
        print(self.__msg) # ShowMessage class
        self._component.operation() # Component


class WriteDecorator(Component):

    def __init__(self, component: Component, file_name, msg):
        self._component = component
        self._file_name = file_name
        self._msg = msg


class WriteMessage(WriteDecorator):

    def operation(self):
        self._component.operation()
        with open(self._file_name, mode='w') as fh:
            fh.write(self._msg)


if __name__ == '__main__':
    show_component = ShowCharComponent('-')
    # show_component.operation()

    show_message = ShowMessage(show_component, 'Hello world')
    # show_message.operation()

    write_message = WriteMessage(show_message, 'tmp.txt', 'Write Message')
    write_message.operation()