📌
デザインパターンを学ぶ #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