pythonにdecorator機能というものがあることを知りました。
pythonのdecorator機能とは、 「関数やクラスの前後に特定の処理を追加できる」ようですが、 GoFのデコレータパターンとは異なるようです。
で、pythonのdecorator機能を試す前に、 GoFデザインパターンの振り返りとして、 以下の「レベルアップJava ~デザインパターン編~」を pythonで実装します。
https://www.amazon.co.jp/dp/B086D2HLKK
実装例
以下の「ミックスアイス」で理解できると思います。
クラス図
┌IceCream(Abstract Class)─────┐ ├─────────────────┤ │+get_price():int(Abstract Method) ├←┐ │+get_name() :str(Abstract Method) │ │ └───┬────────┬────┘ │ △ △ 集約 継承 継承 ◇ ┌Corn─┴────┐┌Ice ┴──────┴┐ │-price:int ││#ice_cream:IceCream │ │-name:str ││ │ ├────────┤├──────────┤ │+get_price():int││+get_price():int │ │+get_name() :str││+get_name() :str │ └────────┘└─┬──┬─────┘ △ △ 継承 継承 ┌Vanilla ┴┐┌┴Chocolate ┐ │-price:int││-price:int │ │-name:str ││-name:str │ ├─────┤├──────┤ └─────┘└──────┘
python script
# -*- coding: utf-8 -*- import abc # Abstract Base Classes モジュール def main(): corn = Corn() vanilla = Vanilla(corn) choco = Chocolate(corn) mix = Chocolate(Vanilla(corn)) print(vanilla.get_name(),vanilla.get_price() ) print(choco.get_name(), choco.get_price() ) print(mix.get_name(), mix.get_price() ) class IceCream(metaclass=abc.ABCMeta): @abc.abstractmethod def get_price(self) -> int: raise NotImplementedError() @abc.abstractmethod def get_name(self) -> str: raise NotImplementedError() class Corn(IceCream): def __init__(self): self.price = 100 self.name = "アイスクリーム" def get_price(self) -> int: return self.price def get_name(self) -> str: return self.name class Ice(IceCream): def __init__(self,ice_cream): self.ice_cream = ice_cream def get_price(self) -> int: return self.price + self.ice_cream.get_price() def get_name(self) -> str: return self.name + self.ice_cream.get_name() class Vanilla(Ice): def __init__(self,ice_cream): super().__init__(ice_cream) self.price = 100 self.name = "バニラ" class Chocolate(Ice): def __init__(self,ice_cream): super().__init__(ice_cream) self.price = 70 self.name = "チョコ" if __name__ == '__main__': main()
↑こう書くと↓こう表示されます
>python foo.py バニラアイスクリーム 200 チョコアイスクリーム 170 チョコバニラアイスクリーム 270