本記事はGoFのデザインパターンの1つであるAdapterパターンについての解説と実際に実装した記事になります。 ソースコード
必要なインタフェースを実装しつつ、既存のクラスにオペレーションの呼び出しを行うようなクラスを作成します。
これによってインタフェースや既存のクラスを変更する必要がなくなります。
方法として以下の2通り。
クラスに適応するAdapterパターンには、多重結合を行うことで、既存のクラスの振る舞いをオーバーライドすることができます。
Targetクラスは print_messge と print_message_with_line の2つのインタフェースを提供するとします。
class Target:
@abstractmethod
def print_message(self):
raise NotImpremetedError()
@abstractmethod
def print_message_with_line(self):
raise NotImpremetedError()
Adapteeクラスは既に show_messgeとshow_message_with_lineを実装ずみとします。
class Adaptee:
def __init__(self, message):
self._message = message
def show_message(self):
print(self._message)
def show_message_with_line(self):
print('---- {} ----'.format(self._message))
TargetクラスのインタフェースでAdapteeクラスの処理を呼び出すには以下のようにAdapterクラスを2つのクラスを継承して作成します。
class Adapter(Adaptee, Target):
def __init__(self, message):
super().__init__(message)
def print_message(self):
self.show_message()
def print_message_with_line(self):
self.show_message_with_line()
target = Adapter('target message')
target.print_message()
target.print_message_with_line()
実行結果
target message
---- target message ----
オブジェクトに適応するAdapterパターンは、オブジェクトコンポジションを使います。
こちらはAdapteeクラスの振る舞いをオーバーライドするのが難しいですが、Adapteeクラスやそのサブクラス、また複数のAdapteeクラスの機能を使うことができます。
class Adapter(Target):
def __init__(self, message):
self._adaptee = Adaptee(message)
def print_message(self):
self._adaptee.show_message()
def print_message_with_line(self):
self._adaptee.show_message_with_line()
クラスに適応するAdapterパターンは、Adapteeクラスの全てのサブクラスを適合したい場合は使うことができません。
また、Adapterクラスが行う物には、簡単なメソッド名の変更から全く異なる処理をサポートすることがまでが考えられますが、TargetクラスのインタフェースがどれだけAdapteeクラスのインタフェースに似ているかによりAdapterクラスの作業量が変わってきます。