KnowHow

技術的なメモを中心にまとめます。
検索にて調べることができます。

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()