Python基礎 オブジェクト指向16(Bridge) 構造に関するデザインパターン
| 登録日 | :2025/10/16 07:16 |
|---|---|
| カテゴリ | :Python基礎 |
Bridge
機能を提供するクラスと、実装を提供するクラスを独立させるためのパターン
- 目的と手段を分離する
- 委譲を行うことで、「機能」と「実装」の橋渡しをしているように見える
構成要素
Abstraction
- 基本機能を提供するクラス
- 内部に「実装」を行うオブジェクトを保持しており、具体的な処理はそのオブジェクトに委譲する
RefinedAbstraction
- Abstractionを継承する子クラス
- 基本機能の拡張や別の機能を追加
Implementor
- 「実装」を提供するインターフェースもしくは抽象クラス
- 機能を実現するためのAPIを定義
- AbstractionのAPIと一致している必要はない
ConcreteImplementor
- Implementorを実装(継承)する子クラス
- 機能の具体的な「実装」を行う
オブジェクト指向的要素
「継承」「ポリモーフィズム」「委譲」を利用したパターン
-
AbstractionとRefinedAbstraction、ImplementorとConcreteImplementorが継承(実装)関係
-
Abstractionの属性を抽象であるImplementorとすることで、具体的な実装を意識する必要がなくなる
-
機能を提供するクラスの具体的な処理は、実装を提供するクラスに委譲される
メリット・デメリット
メリット
- 機能の拡張と実装の修正が容易になる
- プログラムの実行時に実装を切り替えられる
- 機能や実装のバリエーションが豊富な場合、最終的に作成すべきクラス数を抑えることができる
デメリット
- 機能や実装にバリエーションが少ない場合、余計にクラス数が増えコードが複雑になる可能性がある。
使い所
機能と実装の組み合わせが多い場合
- 継承のみで実現する場合、抽象と具体の組み合わせ分(掛け算)のくらす作成が必要である
一方で、Bridgeパターンでは、親クラス(2)+機能数+実装数のクラスを作成する
サンプル
複数のOSからアプリを使ってメッセージを送信する例
from abc import ABCMeta, abstractmethod
class MessageApp(metaclass=ABCMeta):
@abstractmethod
def send(self):
pass
class LINE(MessageApp):
def send(self):
print("LINE Messages.")
class Twitter(MessageApp):
def send(self):
print("Twitter Messages.")
class Facebook(MessageApp):
def send(self):
print("Facebook Messages.")
class OS(metaclass=ABCMeta):
def __init__(self):
self._app = None
def set_app(self, _app: MessageApp):
self._app = _app
@abstractmethod
def send_message(self):
pass
class IOS(OS):
def send_message(self):
print("IOS send messages")
if self._app:
self._app.send()
else:
raise Exception("There is no app.")
class Android(OS):
def send_message(self):
print("Android send messages")
if self._app:
self._app.send()
else:
raise Exception("There is no app.")
if __name__ == "__main__":
line = LINE()
twitter = Twitter()
facebook = Facebook()
ios = IOS()
android = Android()
ios.set_app(line)
android.set_app(facebook)
ios.send_message()
android.send_message()