📌

デザインパターンを学ぶ #8 Bridge(ブリッジ)

に公開

1. はじめに

デザインパターン学習シリーズの第7回。今回は Bridge(ブリッジ)パターン を取り上げます。
目的は 抽象(機能)と実装を分離し、独立に拡張できるようにする 方法を理解することです。

2. Bridge とは?

Bridge パターンは、機能の階層(抽象) と 実装の階層 を分け、両者を委譲で橋渡し(bridge)する設計です。
たとえば「メッセージの種類(Text/HTML)」と「送信方法(Email/Slack)」を別軸に分けておくと、組み合わせが増えてもクラス爆発を防げます。

3. 実装例(PHP)

// 実装側(Implementor)
interface Sender {
    public function send(string $content): void;
}

class EmailSender implements Sender {
    public function send(string $content): void {
        echo "Send via Email: {$content}\n";
    }
}

class SlackSender implements Sender {
    public function send(string $content): void {
        echo "Send via Slack: {$content}\n";
    }
}

// 抽象側(Abstraction)
abstract class Message {
    protected Sender $sender;
    public function __construct(Sender $sender) {
        $this->sender = $sender;
    }
    abstract public function send(string $content): void;
}

class TextMessage extends Message {
    public function send(string $content): void {
        $this->sender->send("[TEXT] {$content}");
    }
}

class HtmlMessage extends Message {
    public function send(string $content): void {
        $this->sender->send("<p>{$content}</p>");
    }
}

// 利用例(組み合わせは実行時に決められる)
$msg = new HtmlMessage(new SlackSender());
$msg->send("System down!");

出力例

Send via Slack: <p>System down!</p>

4. メリットと注意点

メリット

  • 抽象と実装を独立に拡張できる(新しい送信方法や新しいメッセージ形式を片方だけ追加できる)
  • 組み合わせ爆発(HTML×Slack、HTML×Email、…)を避けられる
  • 実装交換が容易(依存逆転/DI と相性が良い)

注意点

  • 小規模な要件ではクラス数が増えて過剰設計になりやすい
  • 抽象と実装の責務境界を最初にきちんと引く必要がある

5. 実務での利用例

  • 通知システム(メッセージ形式 × 送信チャネル)
  • レンダリング(図形API × 出力先:SVG / Canvas / PDF)
  • ストレージ(データ形式 × 保存先:ローカル / S3 / DB)

6. まとめ

Bridge は 機能(抽象)と実装を分離し、実行時に組み合わせる ための構造パターン。
拡張の自由度を高め、継承ベースのクラス爆発を防ぎます。次回は関連の深い Proxy か Facade に進むと理解がつながりやすいです。

Discussion