読者です 読者をやめる 読者になる 読者になる

何かを書き留める何か

数学や読んだ本について書く何かです。最近は社会人として生き残りの術を学ぶ日々です。

Pythonで頑張る『Java言語で学ぶデザインパターン入門』【Adapterパターン】

Python Design Pattern

【前回までの粗筋】
OJT(お前が 自分で トレーニング)

今回はAdapterパターンである。つまりはWrapperである。GoFによると、2つのインタフェース間の非互換性を解消するためのパターンである。
これはわかりやすい。Adapterパターンにはクラスの継承によるものと、インスタンスの委譲によるものの2種類ある。以下のコードは前者に基づいている(つもり)。

'''Adapter
あるクラスのインタフェースを、
クライアントが求めるほかのインターフェースへ変換する。
インタフェースに互換性の無いクラス同士を
組み合わせることが出来るようにする。
'''

import abc

class Banner(object):
    """Adaptee
    適合させる必要がある
    既存のインタフェースを持つ"""
    def __init__(self, string):
        self.string = string
    def showwithparen(self):
        print('(' + self.string + ')')
    def showwithaster(self):
        print('*' + self.string + '*')

class Print(metaclass=abc.ABCMeta):
    """Target
    Clientクラスが利用するドメインに
    特化したインタフェースを定義する"""
    @abc.abstractmethod
    def printweak(self):
        pass
    @abc.abstractmethod
    def printstrong(self):
        pass

class PrintBanner(Print, Banner):
    """Adapter
    Adapteeクラスのインタフェースを
    Targetクラスにインタフェースに適合させる"""
    def __getattr__(self, name):
        return getattr(self.obj, name)
    def printweak(self):
        super().showwithparen()
    def printstrong(self):
        super().showwithaster()

def main():
    """Client
    Targetクラスのインタフェースに従った
    オブジェクトと協力する。"""
    p = PrintBanner('Spam')
    p.printweak() # (Spam)
    p.printstrong() # *Spam*
    
if __name__ == '__main__':
    main()

まあ、単なる画面出力だと味気ないかな…。