Pythonでデザインパターン 拾弐ノ型「Decorator」
今回はPythonの勉強しながらデザインパターンのDecoratorをやってみました。
他のパターンにつきましては、以下の目次記事をご参照ください。
Decoratorとは
直訳すると「飾り付けをする人」ですかね。
wikiには「既存のオブジェクトに新しい機能や振る舞いを動的に追加することを可能にする」とあります。
直訳やwikiから推測するにいまあるオブジェクトに飾り付けを行うためのパターンのようです。
゚+.(◕ฺ ω◕ฺ )゚+.
Decoratorについて考えてみる
今回は顔文字をデコってみたいと思います(・`ω´・)b
まずはデコレーションするベースクラスComponentを用意します。
class Component(metaclass=ABCMeta): @abstractmethod def getTxt(self): pass
そしてComponentを使って顔文字クラスEmoticonを作ります。
class Emoticon(Component): def getTxt(self): return "(^ω^)"
Emoticonクラスだけ使うとこんな感じです。
派手さが足りませんね(・´ω`・)
> print(Emoticon().getTxt())
(^ω^)
次にComponentクラスをデコレートするためのベースクラスDecoratorを用意します。
DecoratorクラスにはComponentクラスを継承させます。
class Decorator(Component): def __init__(self, component: Component) : self._component = component
そしてDecoratorクラスをもとにデコレートするクラスを準備します。
class BanzaiDecorator(Decorator): def __init__(self, component: Component) : super().__init__(component) def getTxt(self): return "ヽ" + self._component.getTxt() + "/"
あとは使うだけですね!
EmoticonクラスをBanzaiDecoratorクラスでラッピングしてデコレートしていますヽ(^ω^)/
> print(BanzaiDecorator(Emoticon()).getTxt())
ヽ(^ω^)/
こんな感じでオブジェクトをラップして機能をデコレートしていくパターンになります。
サンプルコード
顔文字に万歳、Yeah、きらきらをデコレーションしてみます。
# coding: utf-8 from abc import ABCMeta, abstractmethod # コンポーネントクラス class Component(metaclass=ABCMeta): @abstractmethod def getTxt(self): pass # デコレータクラス class Decorator(Component): def __init__(self, component: Component) : self._component = component # 顔文字クラス class Emoticon(Component): def __init__(self, text: str): self._text = text def getTxt(self): return self._text # 万歳デコレータクラス class BanzaiDecorator(Decorator): def __init__(self, component: Component) : super().__init__(component) def getTxt(self): return "ヽ" + self._component.getTxt() + "/" # イエーイデコレータクラス class YeahDecorator(Decorator): def __init__(self, component: Component) : super().__init__(component) def getTxt(self): return "イエェェェェ" + self._component.getTxt() + "ェェェェイィ" # きらきらデコレータクラス class GlitterDecorator(Decorator): def __init__(self, component: Component) : super().__init__(component) def getTxt(self): return "。*:゜☆" + self._component.getTxt() + "☆゜:。*。" if __name__ == "__main__": print(Emoticon("(*´Д`)").getTxt()) print("") print(BanzaiDecorator( Emoticon("(*´Д`)")).getTxt()) print("") print(YeahDecorator( BanzaiDecorator( Emoticon("(*´Д`)"))).getTxt()) print("") print(GlitterDecorator( YeahDecorator( BanzaiDecorator( Emoticon("(*´Д`)")))).getTxt())
結果はこんな感じ。
きれいにデコレーションできましたか???
$ python Decorator.py (*´Д`) ヽ(*´Д`)/ イエェェェェヽ(*´Д`)/ェェェェイィ 。*:゜☆イエェェェェヽ(*´Д`)/ェェェェイィ☆゜:。*。