🧩 Prototype パターン
✅ 設計意図
- オブジェクトを**テンプレートとして複製(clone)**し、差分のみ変更して再利用
- ベタ書きせずに「もと」を再利用できるようにする
✅ 適用理由
- 初期化済みの構造をそのまま複製し、修正・カスタマイズしたいとき
- 可変部分以外を共通化して、複製コストを削減
✅ 向いているシーン
- 通知テンプレート、ボタン構成、共通設定オブジェクトなどのベース複製
✅ コード例
- TypeScript
- PHP
- Python
interface Cloneable<T> {
clone(): T;
}
class Notification implements Cloneable<Notification> {
constructor(
public header: string,
public footer: string,
public user: string = "",
public message: string = ""
) {}
clone(): Notification {
return new Notification(this.header, this.footer);
}
send(): void {
console.log(
`${this.header}\n宛先: ${this.user}\n本文: ${this.message}\n${this.footer}`
);
}
}
// プロトタイプ生成
const prototype = new Notification("件名: お知らせ", "-- 通知システム");
// 利用例
const n1 = prototype.clone();
n1.user = "hiroshi";
n1.message = "こんにちは";
n1.send();
const n2 = prototype.clone();
n2.user = "satoshi";
n2.message = "お知らせがあります";
n2.send();
<?php
class Notification {
public function __construct(
public string $header,
public string $footer,
public string $user = "",
public string $message = ""
) {}
public function clone(): Notification {
return new Notification($this->header, $this->footer);
}
public function send(): void {
echo "{$this->header}\n宛先: {$this->user}\n本文: {$this->message}\n{$this->footer}\n";
}
}
// プロトタイプ生成
$prototype = new Notification("件名: お知らせ", "-- 通知システム");
// 利用例
$n1 = $prototype->clone();
$n1->user = "hiroshi";
$n1->message = "こんにちは";
$n1->send();
$n2 = $prototype->clone();
$n2->user = "satoshi";
$n2->message = "お知らせがあります";
$n2->send();
import copy
class Notification:
def __init__(self, header: str, footer: str, user: str = "", message: str = ""):
self.header = header
self.footer = footer
self.user = user
self.message = message
def clone(self) -> 'Notification':
return copy.deepcopy(self)
def send(self):
print(f"{self.header}\n宛先: {self.user}\n本文: {self.message}\n{self.footer}")
# プロトタイプ生成
prototype = Notification("件名: お知らせ", "-- 通知システム")
# 利用例
n1 = prototype.clone()
n1.user = "hiroshi"
n1.message = "こんにちは"
n1.send()
n2 = prototype.clone()
n2.user = "satoshi"
n2.message = "お知らせがあります"
n2.send()
✅ 解説
このコードは Prototype
パターン を使用して、既存のオブジェクト(Notification
)を複製(クローン)し、
同じプロパティを持つ新しいインスタンスを生成する設計を実現している。
Prototype
パターンは、オブジェクトの生成をクラスに依存せず、既存のインスタンスをコピーして新しいインスタンスを作成するデザインパターン。
1. Prototype パターンの概要
- Prototype: クローン機能を提供するインターフェース
- このコードでは
Cloneable<T>
が該当
- このコードでは
- ConcretePrototype:
Prototype
を実装し、具体的なクローン処理を提供するクラス- このコードでは
Notification
が該当
- このコードでは
- Client:
Prototype
を利用してオブジェクトを複製するコード- このコードでは
prototype.clone()
を呼び出してクローンを生成する部分が該当
- このコードでは
2. 主なクラスとその役割
Cloneable<T>
Prototype
の共通インターフェースclone(): T
メソッドを定義し、オブジェクトのクローンを生成
Notification
ConcretePrototype
クラスclone
メソッドで自身のコピーを生成send
メソッドで通知を送信
- クライアントコード
Notification
のプロトタイプを生成し、clone
メソッドで複製- 複製したインスタンスにユーザーやメッセージを設定して通知を送信
3. UML クラス図
4. Prototype パターンの利点
- オブジェクト生成の柔軟性: クラスに依存せず、既存のインスタンスを基に新しいインスタンスを生成可能
- 複雑な初期化処理の回避: クローンを使用することで、複雑な初期化処理を繰り返す必要がない
- 拡張性: 新しいクラスを追加する場合も、
clone
メソッドを実装するだけで対応可能
この設計は、既存のオブジェクトを基に新しいインスタンスを生成する必要がある場面で非常に有効であり、コードの柔軟性と再利用性を向上させる。