🧩 Bridge パターン
✅ 設計意図
- 抽象と実装を分離し、それぞれを独立に拡張可能にする
- 「通知内容」と「通知方法」のように、独立した変化軸を持つ構成を設計できる
✅ 適用理由
- 通知方法(メール、Slack)と通知内容(警告、お知らせ)を別の軸で切り替えたい
- 拡張パターンが組み合わせによって爆発しそうなときに有効
✅ 向いているシーン
- 複数の軸で拡張・組み合わせが必要な場合(表示方式 × 出力先、など)
✅ コード例
- TypeScript
- PHP
- Python
// 実装クラス(通知手段)
interface Notifier {
sendMessage(to: string, content: string): void;
}
class EmailNotifier implements Notifier {
sendMessage(to: string, content: string): void {
console.log("件名: お知らせ");
console.log(`本文: ${content}`);
console.log(`宛先: ${to}@example.com`);
}
}
class SlackNotifier implements Notifier {
sendMessage(to: string, content: string): void {
console.log(`Slack宛: ${to}`);
console.log(`内容: ${content}`);
}
}
// 抽象クラス(通知処理)
abstract class Notification {
constructor(protected notifier: Notifier) {}
abstract notify(user: string, message: string): void;
}
// 拡張された抽象クラス
class NormalNotification extends Notification {
notify(user: string, message: string): void {
this.notifier.sendMessage(user, message);
}
}
class UrgentNotification extends Notification {
notify(user: string, message: string): void {
this.notifier.sendMessage(user, `[緊急] ${message}`);
}
}
// 利用例
const emailUrgent = new UrgentNotification(new EmailNotifier());
emailUrgent.notify("hiroshi", "サーバーが落ちました");
const slackNormal = new NormalNotification(new SlackNotifier());
slackNormal.notify("hiroshi", "定例ミーティングは15時です");
<?php
interface Notifier {
public function sendMessage(string $to, string $content): void;
}
class EmailNotifier implements Notifier {
public function sendMessage(string $to, string $content): void {
echo "件名: お知らせ\n";
echo "本文: {$content}\n";
echo "宛先: {$to}@example.com\n";
}
}
class SlackNotifier implements Notifier {
public function sendMessage(string $to, string $content): void {
echo "Slack宛: {$to}\n";
echo "内容: {$content}\n";
}
}
abstract class Notification {
public function __construct(protected Notifier $notifier) {}
abstract public function notify(string $user, string $message): void;
}
class NormalNotification extends Notification {
public function notify(string $user, string $message): void {
$this->notifier->sendMessage($user, $message);
}
}
class UrgentNotification extends Notification {
public function notify(string $user, string $message): void {
$this->notifier->sendMessage($user, "[緊急] {$message}");
}
}
// 利用例
$notification1 = new UrgentNotification(new EmailNotifier());
$notification1->notify("hiroshi", "サーバーが落ちました");
$notification2 = new NormalNotification(new SlackNotifier());
$notification2->notify("hiroshi", "定例ミーティングは15時です");
from abc import ABC, abstractmethod
# 実装側(Bridge の下部)
class Notifier(ABC):
@abstractmethod
def send_message(self, to: str, content: str):
pass
class EmailNotifier(Notifier):
def send_message(self, to: str, content: str):
print("件名: お知らせ")
print(f"本文: {content}")
print(f"宛先: {to}@example.com")
class SlackNotifier(Notifier):
def send_message(self, to: str, content: str):
print(f"Slack宛: {to}")
print(f"内容: {content}")
# 抽象側(Bridge の上部)
class Notification(ABC):
def __init__(self, notifier: Notifier):
self.notifier = notifier
@abstractmethod
def notify(self, user: str, message: str):
pass
class NormalNotification(Notification):
def notify(self, user: str, message: str):
self.notifier.send_message(user, message)
class UrgentNotification(Notification):
def notify(self, user: str, message: str):
self.notifier.send_message(user, f"[緊急] {message}")
# 利用例
email_urgent = UrgentNotification(EmailNotifier())
email_urgent.notify("hiroshi", "サーバーが落ちました")
slack_normal = NormalNotification(SlackNotifier())
slack_normal.notify("hiroshi", "定例ミーティングは15時です")
✅ 解説
このコードは Bridge
パターン を使用して、通知手段(Notifier
)と通知処理(Notification
)を分離し、
それぞれを独立して拡張可能にする設計を実現している。
Bridge
パターンは、抽象部分と実装部分を分離し、それぞれを独立して変更できるようにするデザインパターン。
1. Bridge パターンの概要
- Abstraction: 抽象部分を定義するクラス
- このコードでは
Notification
が該当
- このコードでは
- RefinedAbstraction:
Abstraction
を拡張したクラス- このコードでは
NormalNotification
とUrgentNotification
が該当
- このコードでは
- Implementor: 実装部分を定義するインターフェース
- このコードでは
Notifier
が該当
- このコードでは
- ConcreteImplementor:
Implementor
を実装した具体的なクラス- このコードでは
EmailNotifier
とSlackNotifier
が該当
- このコードでは
2. 主なクラスとその役割
Notifier
- 実装部分の共通インターフェース
sendMessage(to: string, content: string): void
メソッドを定義
EmailNotifier
,SlackNotifier
Notifier
を実装した具体的なクラス- メールまたは Slack を使用してメッセージを送信
Notification
- 抽象部分の基底クラス
Notifier
を保持し、通知処理を定義
NormalNotification
,UrgentNotification
Notification
を拡張した具体的なクラス- 通常通知や緊急通知の処理を実装
3. UML クラス図
4. Bridge パターンの利点
- 抽象と実装の分離: 抽象部分(
Notification
)と実装部分(Notifier
)を分離することで、それぞれを独立して変更可能 - 柔軟性: 新しい通知手段や通知処理を追加する場合も、既存のコードに影響を与えずに拡張可能
- コードの再利用性: 抽象部分と実装部分を組み合わせることで、コードの再利用性が向上
この設計は、異なる実装を持つ機能を柔軟に組み合わせる必要がある場面で非常に有効であり、コードの拡張性と保守性を向上させる。