概要
Bridge(ブリッジ)パターンは、
抽象部分(Abstraction)と具体的な実装部分(Implementation)を独立して分離し、それぞれを別々に拡張可能にする設計パターンである。
「継承による階層の爆発」や「実装依存による抽象の硬直化」を防ぎ、柔軟かつ拡張性の高いアーキテクチャを構築するのに有効。
1. なぜBridgeが必要か?
❌ 抽象と実装が密結合だと、組み合わせに爆発的なクラス数が必要になる
例:
- Shape(形) × Renderer(描画方法)
→VectorCircle
,RasterCircle
,VectorSquare
,RasterSquare
… ×2でクラス爆発
✅ Bridgeにより、抽象と実装を別レイヤーとして独立に構成
circle = Circle(renderer)
circle.draw()
→ Rendererを入れ替えるだけで、同じ抽象構造で異なる描画を実現可能
2. 基本構造
✅ Implementor(実装のインターフェース)
class Renderer:
def render_circle(self, radius):
raise NotImplementedError
✅ ConcreteImplementor(具体的な実装)
class VectorRenderer(Renderer):
def render_circle(self, radius):
print(f"ベクターで円を描画(半径: {radius})")
class RasterRenderer(Renderer):
def render_circle(self, radius):
print(f"ラスタで円を描画(ピクセルベース、半径: {radius})")
✅ Abstraction(抽象)
class Shape:
def __init__(self, renderer: Renderer):
self.renderer = renderer
def draw(self):
raise NotImplementedError
✅ RefinedAbstraction(具体的な抽象)
class Circle(Shape):
def __init__(self, renderer: Renderer, radius):
super().__init__(renderer)
self.radius = radius
def draw(self):
self.renderer.render_circle(self.radius)
✅ 使用例
vector = VectorRenderer()
raster = RasterRenderer()
circle1 = Circle(vector, 5)
circle2 = Circle(raster, 10)
circle1.draw()
circle2.draw()
出力:
ベクターで円を描画(半径: 5)
ラスタで円を描画(ピクセルベース、半径: 10)
3. Python的応用:依存性注入を通じてBridge構造を自然に実装
class Logger:
def log(self, msg): raise NotImplementedError
class FileLogger(Logger):
def log(self, msg): print(f"[FILE] {msg}")
class ConsoleLogger(Logger):
def log(self, msg): print(f"[CONSOLE] {msg}")
class App:
def __init__(self, logger: Logger):
self.logger = logger
def process(self):
self.logger.log("アプリケーション処理開始")
→ AppはLoggerに依存しており、Bridgeによって実装に縛られない
4. 実務ユースケース
✅ GUIライブラリのプラットフォーム依存抽象化
→ 抽象Widget + OSごとのRenderer
✅ ストレージ層(S3 / ローカル / DB)とアップロードAPIの分離
→ UploadService ⇄ StorageBackend
✅ ドキュメント出力(PDF / HTML / Markdown)の出力方式分離
→ Report ⇄ Renderer構造で表現
✅ 機械学習モデルの推論エンジン切り替え(TensorFlow / PyTorch)
→ ModelInterface ⇄ BackendExecutor
5. よくある誤用と対策
❌ 実装が少ないのにBridge構造にしてしまい複雑化
→ ✅ 抽象・実装が独立進化する可能性があるときだけ導入
❌ 実装部分の責務が過剰になりすぎる
→ ✅ Rendererや実装側に必要最小限の処理のみを委任
❌ 二重の継承関係で理解が難しくなる
→ ✅ 命名と責務の明確化で可読性を維持する
結語
Bridgeパターンとは、“抽象と実装を橋で繋ぎ、自由な進化を可能にする設計”である。
- 実装と抽象を分離することで、爆発的なクラス増加を抑え、柔軟な拡張を可能にする
- 単一責任を保ちつつ、アーキテクチャの構造を整理する鍵となる設計
- Pythonでは依存性注入と動的型によって、極めて自然かつ強力に実現可能
Pythonicとは、“抽象と実装を結ぶ橋を設計すること”。
Bridgeパターンはその橋の知性を、設計の進化力として表現する技法である。