0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで実装するBridgeパターン:抽象と実装の分離によるスケーラブルな設計

Posted at

概要

Bridge(ブリッジ)パターンは、
抽象(Abstraction)と実装(Implementation)を別々の階層に分けて独立に拡張可能にする設計パターンである。

継承に頼らず、"has-a" 関係をベースに拡張性と柔軟性を担保し、機能とプラットフォームの組み合わせ爆発を防ぐ。


1. なぜBridgeが必要か?

❌ 継承で機能・実装を両方組み合わせるとクラス数が爆発する

class WindowsButton: ...
class MacButton: ...
class WindowsCheckbox: ...
class MacCheckbox: ...

新しいプラットフォームやUI要素を追加するたびにクラスが倍増


✅ 抽象と実装を分離し、それぞれを独立に拡張可能にする

ui = Button(WindowsRenderer())
ui.draw()

「何をするか」と「どうやるか」を切り離し、柔軟に構成可能


2. 基本構造

✅ Implementation層(実装のインターフェース)

class Renderer:
    def render_button(self, label):
        raise NotImplementedError

✅ Concrete Implementations(具体的な描画方法)

class WindowsRenderer(Renderer):
    def render_button(self, label):
        print(f"[Windows] ボタン: {label}")

class MacRenderer(Renderer):
    def render_button(self, label):
        print(f"[Mac] ボタン: {label}")

✅ Abstraction層(抽象のインターフェース)

class UIElement:
    def __init__(self, renderer: Renderer):
        self.renderer = renderer

    def draw(self):
        raise NotImplementedError

✅ Refined Abstraction(具体的なUI)

class Button(UIElement):
    def __init__(self, label, renderer):
        super().__init__(renderer)
        self.label = label

    def draw(self):
        self.renderer.render_button(self.label)

✅ 使用例

btn1 = Button("保存", WindowsRenderer())
btn2 = Button("保存", MacRenderer())

btn1.draw()
btn2.draw()

出力:

[Windows] ボタン: 保存  
[Mac] ボタン: 保存

3. Python的応用:関数型Bridgeでさらにシンプルに

def render_button_windows(label):
    print(f"(Win) {label} ボタン描画")

def render_button_mac(label):
    print(f"(Mac) {label} ボタン描画")

class Button:
    def __init__(self, label, render_func):
        self.label = label
        self.render = render_func

    def draw(self):
        self.render(self.label)
b = Button("送信", render_button_windows)
b.draw()

Pythonでは関数レベルでもBridge的構造を表現可能


4. 実務ユースケース

✅ UIツールキットにおけるクロスプラットフォーム描画

ボタン・入力欄などをOSごとに実装を切り替えて提供


✅ データの送信ロジックと転送プロトコルの分離(HTTP, WebSocket, gRPC)

高レイヤーの抽象と低レイヤーの実装を疎結合で構成


✅ ログ出力とその媒体(コンソール、ファイル、リモート)

同じ抽象操作を異なるバックエンドに橋渡し


✅ 支払い処理の戦略とプラットフォーム対応の分離

Payment(paypal), Payment(stripe) のような動的切替が可能


5. よくある誤用と対策

❌ 実装と抽象が再び密結合になる

→ ✅ コンストラクタ注入を基本とし、実装の依存を明示的に外出し


❌ 継承の代替としての誤用(責務の分離がされていない)

→ ✅ 抽象=“意図”、実装=“手段” と明確に分離


❌ 抽象層が何を意味しているか不明確

→ ✅ ドメインモデルを先に設計し、何を分離すべきかを明示化する


結語

Bridgeパターンとは、“意図と手段の階層を分け、柔軟に結合し直す設計”である。

  • 抽象と実装の独立を保つことで、機能の組み合わせ爆発を回避
  • 継承よりも柔軟で、設計の方向性を自由に描き出せる
  • Pythonではクラス・関数・依存注入によって、極めて簡潔かつ強力に表現できる

Pythonicとは、“機能と表現のレイヤーを分けて保ち、変化にしなやかに対応すること”。
Bridgeパターンはその分離と再構築の哲学を、設計の骨格に刻む技法である。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?