mcpField
G
gof-bridge

gof-bridge

github.com/yonatankarp開発143 回インストール23 週間前に更新
リポジトリ

gof-bridge について

抽象と実装を独立して変更するシステムの設計者向けに、GoF の Bridge パターンを解説するスキルです。コンポジション、実装の実行時切り替え、Adapter や Strategy との違いを扱います。

主な機能

  1. 01抽象と実装の分離
  2. 02並行するクラス階層の利用
  3. 03実行時の実装切り替え
  4. 04Bridge と Adapter の比較
  5. 05判断基準と注意点

活用シーン

  1. 01複数の形状とレンダラーへの対応
  2. 02抽象と実装の独立した進化
  3. 03プラットフォームや設定によるレンダラー選択

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/yonatankarp/software-design-skills --skill gof-bridge

インストール後、Claude Code で/gof-bridgeを入力して読み込まれたか確認します。

詳細

1 行での概要

抽象とその実装を切り離し、互いに独立して変更できるようにします。組み合わせによるサブクラスの爆発を、直交する 2 つの軸に沿ったコンポジションに置き換えます。

このスキルを使う場面

  • 直交する 2 つの変化軸がある場合:N 種類の形状 × M 種類のレンダラー、または N 種類の描画ツール × M 種類のレンダリングバックエンド。Bridge を使わないと、N×M のサブクラスが必要になります。
  • 抽象(例:Shape)と実装(例:Renderer)の両方が、場合によっては異なるチームによって保守されながら、時間とともに独立して進化していくと見込まれる場合。
  • 実行時に実装を切り替えたい場合。プラットフォーム、環境、設定ごとに別のレンダラーを選べます。

このスキルを使わない場面

  • 2 つの軸のうち、実際に変化するのが一方だけの場合。もう一方には実装が 1 つしかなく、別の実装も見込まれません。Bridge は過剰な設計です。
  • 「2 つの軸」が実際には直交しておらず、互いに連動して結合を強いる場合。Bridge の価値は独立性に依存します。
  • 既存の互換性のない 2 つのインターフェースを後付けで連携させる場合。それは Bridge ではなく gof-adapter です。Bridge はあらかじめ設計するものです。

主な内容

2 つの並行する階層:

  • 抽象 — クライアント向けの概念(Shape、RemoteControl、Notification)。Implementor への参照を保持します。
  • Implementor — 基盤となるインターフェース(Renderer、Device、DeliveryChannel)。具象 Implementor は実行時に組み込まれます。

抽象は保持している Implementor に具体的な処理を委譲します。2 つの階層は独立して拡張できます。新しい Shape を追加しても新しい Renderer サブクラスは不要で、その逆も同様です。

abstract class Shape(val renderer: Renderer) {
    abstract fun draw()
}

interface Renderer { fun renderCircle(x, y, r); fun renderSquare(x, y, s) }

class Circle(renderer: Renderer, val x, y, r): Shape(renderer) {
    override fun draw() = renderer.renderCircle(x, y, r)
}
class VectorRenderer: Renderer { ... }
class RasterRenderer: Renderer { ... }

新しい Shape(Triangle)を追加するには、任意の Renderer で描画する方法を定義します。新しい Renderer(SVGRenderer)を追加すれば、既存のすべての Shape がそのまま SVG で動作します。

Bridge と Adapter の違い。 コンポジションの構造は同じですが、意図と導入時期が異なります:

  • Adapter は互換性のないインターフェースを後付けで連携させます。多くの場合、システムの境界で適用されます。
  • Bridge は抽象と実装を切り離すために意図的に選択する設計で、両者が変化できるよう、あらかじめ設計します。

判断の目安

  • 両方の軸に 2 種類以上のバリエーションがあり、さらに増えると見込まれる場合、Bridge の効果が得られます。
  • 実装だけが変化し、抽象が固定されている場合、それは Bridge ではなく gof-strategy です。
  • Implementor はコンストラクター(または DI)で注入し、抽象を変更せずに差し替えられるようにします。

アンチパターン

  • 実際には一方しか変化しないのに Bridge を導入すること。サブクラスが 1 つだけの抽象クラスと、実装が 1 つだけのインターフェースでは、無用な形式にすぎません。
  • Implementor が抽象の API に漏れ出す Bridge。分離の目的が損なわれます。
  • 抽象のコンストラクター内で Implementor の選択をハードコードすること。Bridge で解消するはずだった結合が残ります。

関連項目

  • gof-adapter — 同じコンポジション構造を使い、既存の互換性のないインターフェースを後付けで連携させます。
  • gof-strategy — 変化する軸が実装の 1 つだけの Bridge です。
  • gof-kotlin-idioms — Kotlin の Bridge は多くの場合、インターフェースをパラメーターに取るコンポジションだけで実現でき、抽象クラスは不要です。

参考資料

  • Design Patterns(GoF、1994 年)、第 4 章 — Bridge。(HFDP 第 2 版には含まれていません。)
  • Kotlin Design Patterns and Best Practices(Alexey Soshin)、第 3 章 — Bridge。

コメント