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