Featured image of post Prototypeパターン調査ドキュメント

Prototypeパターン調査ドキュメント

Prototypeパターン(GoFデザインパターン)に関する調査結果

Prototypeパターン調査ドキュメント

調査概要

  • 調査目的: 「Mooで覚えるオブジェクト指向プログラミング」シリーズを読了した読者が、Prototypeパターンを自然に学べる教材作成のための基礎資料
  • 調査実施日: 2026年1月13日
  • 技術スタック: Perl v5.36以降 / Moo / MooX::Clone
  • 想定読者: オブジェクト指向の基礎が理解できている読者
  • 難易度評価: 2/5(他の生成パターンと比べてシンプル、clone()メソッドの理解が主)
  • 前提知識: 「Mooで覚えるオブジェクト指向プログラミング」シリーズ(全12回)の基本理解済み

1. Prototypeパターンの基礎

1.1 定義と目的

要点:

  • Prototypeパターンは、GoF(Gang of Four)の**生成パターン(Creational Patterns)**の1つ
  • 「既存のオブジェクトをコピー(クローン)して新しいオブジェクトを作成する」
  • コンストラクタやファクトリメソッドを使わずに、プロトタイプとなるオブジェクトを複製して新しいインスタンスを生成する
  • オブジェクト生成コストが高い場合や、実行時に動的にオブジェクトの種類を決定したい場合に有効

GoF原典での定義:

“Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.”

「プロトタイプとなるインスタンスを使って生成するオブジェクトの種類を指定し、このプロトタイプをコピーして新しいオブジェクトを生成する」

パターンの本質:

  • 「new」でインスタンス化するのではなく、既存オブジェクトを「clone」して新しいオブジェクトを作る
  • クラスの階層構造を変更せずに、実行時に柔軟にオブジェクトを生成できる
  • 複雑な初期化処理を省略し、既に設定済みのオブジェクトをベースに効率的に生成

根拠:

  • GoF書籍「Design Patterns: Elements of Reusable Object-Oriented Software」(1994年)で定義
  • Refactoring Guru、GeeksforGeeks、Wikipedia等の主要技術サイトで一致した説明

仮定:

  • 読者は「Mooで覚えるオブジェクト指向プログラミング」シリーズでオブジェクト生成の基礎を学んでいる

出典:

信頼度: 9/10(GoF原典および複数の信頼できる技術サイト)


1.2 GoFパターンにおける位置づけ

要点:

Prototypeは、GoFの23パターンのうち生成パターン(Creational Patterns)5種類の1つです。

パターン名概要
Singletonクラスのインスタンスが1つだけであることを保証し、グローバルアクセスポイントを提供
Factory Methodオブジェクト生成のインターフェースを定義し、サブクラスがインスタンス化するクラスを決定
Abstract Factory関連するオブジェクト群を、具体クラスを指定せずに生成するインターフェースを提供
Builder複雑なオブジェクトの構築プロセスを段階的に行い、同じ構築過程で異なる表現を可能にする
Prototype既存のインスタンスをコピー(クローン)して新しいオブジェクトを作成

生成パターンの中での特徴:

比較軸Prototype他の生成パターン
生成方法既存オブジェクトのコピーnew / ファクトリメソッド
クラス依存性低い(具体クラスを知らなくてよい)Factory Method等は継承が必要
状態の再利用既存オブジェクトの状態を引き継ぐ新規に状態を設定
適用場面生成コストが高い、動的な種類決定クラス階層で種類を管理

根拠:

  • GoFの分類体系で明確に定義されている
  • 生成パターンはオブジェクトの生成メカニズムに関するパターン

出典:

信頼度: 9/10


2. Prototypeパターンの構造

2.1 UML図

	classDiagram
    class Prototype {
        <<interface>>
        +clone() Prototype
    }
    class ConcretePrototype1 {
        -field1
        -field2
        +clone() Prototype
    }
    class ConcretePrototype2 {
        -field1
        -field2
        +clone() Prototype
    }
    class Client {
        +operation()
    }
    
    Prototype <|.. ConcretePrototype1
    Prototype <|.. ConcretePrototype2
    Client --> Prototype : uses

テキスト版UML:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    +-------------------+
    |   <<interface>>   |
    |     Prototype     |
    +-------------------+
    | +clone(): Proto   |
    +-------------------+
            ^
            |
    +-------+-------+
    |               |
+-------------------+  +-------------------+
| ConcreteProto1    |  | ConcreteProto2    |
+-------------------+  +-------------------+
| -field1           |  | -field1           |
| -field2           |  | -field2           |
+-------------------+  +-------------------+
| +clone(): Proto   |  | +clone(): Proto   |
+-------------------+  +-------------------+

        +-------------------+
        |      Client       |
        +-------------------+
        | +operation()      |
        +-------------------+
              |
              | uses
              v
        +-------------------+
        |     Prototype     |
        +-------------------+

信頼度: 9/10


2.2 構成要素の説明

要素役割Perl/Moo実装での具体例
Prototype(プロトタイプ)clone()メソッドを宣言するインターフェースMoo::Rolerequires 'clone'を宣言、またはMooX::Cloneを使用
ConcretePrototype(具象プロトタイプ)clone()メソッドを実装し、自分自身のコピーを返す具体クラスDocumentShapeなど、cloneメソッドを持つクラス
Client(クライアント)プロトタイプのclone()を呼び出して新しいオブジェクトを取得メインスクリプトや利用側のコード

clone()メソッドの役割:

  • オブジェクト自身のコピーを作成して返す
  • 呼び出し側は具体的なクラスを知らなくても、clone()だけで新しいオブジェクトを取得できる
  • 浅いコピー(shallow copy)か深いコピー(deep copy)かは実装による

根拠:

  • GoF原典の構造定義
  • OO Design、Software Pattern Lexicon等のUML解説サイト

出典:

信頼度: 9/10


3. Prototypeパターンの適用場面

3.1 どのような問題を解決するか

要点:

Prototypeパターンは以下の問題を解決します:

  1. オブジェクト生成コストが高い場合

    • データベースアクセス、ネットワーク通信、複雑な計算が必要な初期化
    • 一度生成したオブジェクトをコピーすることで、初期化コストを回避
  2. 実行時にオブジェクトの種類を動的に決定したい場合

    • コンパイル時に具体クラスを指定できない
    • ユーザー入力や設定に基づいて、異なる種類のオブジェクトを生成
  3. Factory Methodのサブクラス爆発を避けたい場合

    • 各製品タイプに対してファクトリクラスを作る必要がない
    • プロトタイプを登録して、必要に応じてクローン
  4. 状態を持つオブジェクトを効率的に複製したい場合

    • 設定済みのオブジェクトをテンプレートとして再利用
    • 少しだけ異なるオブジェクトを多数生成

出典:

信頼度: 9/10


3.2 典型的なユースケース

ユースケース説明具体例
ゲーム開発キャラクターや敵オブジェクトのクローン敵キャラクターのテンプレートをクローンして個別にカスタマイズ
ドキュメントエディタ図形やテキストボックスの複製ユーザーがCtrl+Dで図形を複製する機能
テンプレートシステムドキュメントテンプレートの複製請求書テンプレートをクローンして個別の請求書を作成
GUIライブラリウィジェットの複製スタイル設定済みのボタンをクローンして配置
設定オブジェクトデフォルト設定のコピーデフォルト設定をクローンしてユーザー設定を作成
キャッシュ/レジストリ頻繁に使うオブジェクトのプールプロトタイプレジストリから必要な種類をクローン

出典:

信頼度: 9/10


3.3 他の生成パターンとの比較

Factory Method との違い

項目PrototypeFactory Method
生成方法既存オブジェクトのクローンnewでインスタンス化
クラス階層不要(クローンするだけ)サブクラス化が必要
柔軟性実行時に種類を決定コンパイル時にクラス階層で決定
状態の引き継ぎ元オブジェクトの状態を継承新規に状態を設定
適用場面生成コストが高い、動的決定製品種類が固定、継承で拡張

Abstract Factory との違い

項目PrototypeAbstract Factory
生成対象単一オブジェクトのコピー関連するオブジェクト群(ファミリー)
生成方法clone()createProductA(), createProductB()
登録方式プロトタイプを登録ファクトリを登録
複雑度シンプルやや複雑

Builder との違い

項目PrototypeBuilder
生成方法既存オブジェクトのコピー段階的な構築
適用場面既存オブジェクトを再利用複雑なオブジェクトを一から構築
状態既存の状態をコピー各ステップで状態を設定
生成結果元オブジェクトと同じ構造同じクラスの異なる構成

Singleton との違い

項目PrototypeSingleton
インスタンス数複数(クローンを生成)1つだけ
目的オブジェクトの複製唯一のインスタンスを保証
生成方法clone()instance()

出典:

信頼度: 9/10


4. メリット・デメリット

4.1 メリット

メリット説明実践的な効果
生成コストの削減複雑な初期化処理を省略できるデータベースアクセスや重い計算を回避
具体クラスからの独立クライアントは具体クラスを知らなくてよい疎結合な設計が可能
実行時の柔軟性動的にオブジェクトの種類を決定できる設定やユーザー入力に基づく生成
状態の再利用設定済みオブジェクトをベースに複製テンプレートパターン的な利用
サブクラス爆発の回避Factory Methodほどクラス数が増えないシンプルな設計を維持

信頼度: 9/10


4.2 デメリット

デメリット説明対策
深いコピーの実装が複雑ネストしたオブジェクトの複製が難しいStorable::dclone()やClone::clone()を活用
循環参照への対処相互参照するオブジェクトのクローンは複雑適切なライブラリを使用、設計を見直す
clone()メソッドの保守オブジェクト構造が変わるとcloneも修正必要MooX::Cloneなど自動化されたツールを使用
メモリ消費大量のクローンはメモリを消費必要に応じてFlyweightパターンと組み合わせ

信頼度: 9/10


4.3 いつ使うべきか

適用すべき場面:

  1. オブジェクトの生成コストが高い場合

    • 初期化に時間がかかる、外部リソースにアクセスする
  2. 実行時にオブジェクトの種類を決定する必要がある場合

    • コンパイル時に具体クラスを指定できない
  3. 類似したオブジェクトを大量に生成する場合

    • テンプレートをベースに少しずつ異なるオブジェクトを作成
  4. Factory Methodのサブクラス爆発を避けたい場合

    • プロトタイプレジストリで動的に管理

適用すべきでない場面:

  1. オブジェクト生成がシンプルな場合

    • newで十分、わざわざcloneを実装する必要がない
  2. クローンが複雑になる場合

    • 循環参照が多い、深いネストがある
  3. 状態を引き継ぎたくない場合

    • 毎回新しい状態で始めたい

信頼度: 9/10


5. Perlでの実装方法

5.1 浅いコピー(Shallow Copy)と深いコピー(Deep Copy)

浅いコピー(Shallow Copy):

  • トップレベルの構造だけをコピー
  • ネストした参照は元のオブジェクトと共有
  • 元のオブジェクトを変更すると、コピーにも影響する場合がある
1
2
3
4
5
6
7
8
9
# 浅いコピーの例(問題あり)
my %copy = %original;    # ハッシュの浅いコピー
my @copy = @original;    # 配列の浅いコピー

# ネストした参照は共有される(配列内のハッシュリファレンスは同じメモリを指す)
my @original = ({ name => 'Buster' }, 'Ginger');
my @copy = @original;
# $copy[0] と $original[0] は同じハッシュリファレンスを共有している
$copy[0]{name} = 'Roscoe';  # @original[0]{name} も 'Roscoe' に変わってしまう!

深いコピー(Deep Copy):

  • 再帰的にすべての参照をコピー
  • 元のオブジェクトとは完全に独立
  • 安全にオブジェクトを複製できる
1
2
3
4
5
use Storable qw(dclone);

my @original = ({ name => 'Buster' }, 'Ginger');
my $copy = dclone(\@original);
$copy->[0]{name} = 'Roscoe';  # @original は変わらない!

出典:

信頼度: 9/10


5.2 Storable::dclone()の使用

要点:

Storableモジュールのdclone()は、Perl標準の深いコピー関数です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
use Storable qw(dclone);

# dcloneは参照を受け取り、参照を返す
my $deep_copy = dclone($structure_ref);

# 配列の深いコピー
my @copy = @{ dclone(\@original) };

# ハッシュの深いコピー
my %copy = %{ dclone(\%original) };

特徴:

  • Perl標準モジュール(追加インストール不要)
  • ほとんどのPerlデータ構造に対応
  • blessされたオブジェクトも複製可能
  • 深くネストした構造でも確実に複製

出典:

信頼度: 9/10


5.3 Clone::clone()の使用

要点:

Cloneモジュールは、高速な深いコピーを提供するCPANモジュールです。

1
2
3
use Clone qw(clone);

my $deep_copy = clone($structure_ref);

Storable::dclone()との比較:

項目Clone::clone()Storable::dclone()
インストールCPANから追加インストール必要Perl標準モジュール
速度(浅い構造)高速やや遅い
速度(深い構造)やや遅い高速
互換性高い高い
XS実装あり(高速)あり

出典:

信頼度: 9/10


5.4 MooX::Cloneを使った実装

要点:

MooX::Cloneは、Mooオブジェクトにclone()メソッドを追加するモジュールです。Prototypeパターンの実装に最適です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package Document;
use Moo;
use MooX::Clone;

has 'title'   => (is => 'rw');
has 'content' => (is => 'rw');

package main;

# プロトタイプの作成
my $prototype = Document->new(
    title   => 'テンプレート',
    content => 'デフォルトの内容',
);

# クローンの作成
my $copy = $prototype->clone;

# クローンを独立して変更
$copy->title('新しいドキュメント');

say $prototype->title;  # 出力: テンプレート
say $copy->title;       # 出力: 新しいドキュメント

MooX::Cloneの特徴:

  • Mooオブジェクトにclone()メソッドを自動追加
  • 内部でCloneモジュールを使用(深いコピー)
  • 最小限のボイラープレート
  • Prototypeパターンの実装に最適

出典:

信頼度: 9/10


5.5 Moo/Moo::Roleを使った自前実装

要点:

MooX::Cloneを使わずに、自分でclone()メソッドを実装することもできます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Cloneable Role
package Cloneable;
use Moo::Role;
use Storable qw(dclone);

sub clone ($self) {
    my $class = ref($self);
    # 注意: Mooオブジェクトは内部的にハッシュリファレンスとして実装されているが、
    # 本番コードではMooのメタ情報を使用するか、MooX::Cloneを使用することを推奨
    my %attributes = %{$self};
    return $class->new( %{ dclone(\%attributes) } );
}

1;

# 具象プロトタイプ
package Shape;
use Moo;
use v5.36;
with 'Cloneable';

has 'x'     => (is => 'rw', default => 0);
has 'y'     => (is => 'rw', default => 0);
has 'color' => (is => 'rw', default => 'black');

1;

# 使用例
my $original = Shape->new(x => 10, y => 20, color => 'red');
my $copy = $original->clone;
$copy->x(100);

say $original->x;  # 10
say $copy->x;      # 100

自前実装のメリット:

  • 依存モジュールを減らせる
  • クローン処理をカスタマイズできる(一部の属性を除外するなど)

自前実装のデメリット:

  • ネストしたオブジェクトの処理が複雑
  • MooX::Cloneに比べてコード量が増える

信頼度: 9/10


6. 既存シリーズとの重複チェック

6.1 /content/post配下の調査結果

調査方法: prototype|Prototype|clone|Clone でgrepを実行

結果:

  • Prototypeパターンを直接扱っている既存シリーズは存在しない
  • cloneという単語は出現するが、デザインパターンとしてのPrototypeとは関係がない内容

確認された記事:

  • 一部の記事で「clone」という単語が使われているが、git clone や一般的な「複製」の意味で使用されており、デザインパターンとしてのPrototypeパターンを解説しているものはなし

6.2 他のデザインパターンシリーズとの差別化

シリーズパターンアプローチPrototypeとの違い
ディスパッチャーを作ろうStrategy委譲(has + Role)Strategyは「振る舞い」、Prototypeは「生成」
データエクスポーターを作ろうStrategy委譲(has + Role)同上
設定ファイルマネージャーを作ろう(予定)Singletoninstance()メソッドSingletonは「1つだけ」、Prototypeは「複製」
レポートジェネレーターを作ろう(予定)Factory Method継承(extends)Factory Methodは「new」、Prototypeは「clone」

差別化ポイント:

  • Prototypeは唯一の「クローンベース」パターン: 他の生成パターンは継承やメソッド呼び出しで生成するが、Prototypeは既存オブジェクトのコピーで生成
  • MooX::Cloneという新しいモジュールの紹介: 既存シリーズでは使用していない
  • 浅いコピー/深いコピーの解説: Perl特有のデータ構造の扱いを学べる

信頼度: 9/10


7. 競合分析

7.1 既存記事の調査

検索クエリ見つかった記事特徴
「Prototype パターン Perl」ほぼなし日本語での解説記事が極めて少ない
「Perl clone」Stack Overflow、PerlMonksclone()関数の使い方が中心、パターンとしての解説は少ない
「Prototype pattern」(英語)Refactoring Guru、GeeksforGeeksJava/Python/TypeScript中心、Perl向けはほぼなし
「design patterns perl moo」GitHub (manwar/design-patterns)MooseX::Clone使用、Moo向けは少ない

7.2 既存チュートリアルの強み・弱み

強み(参考にすべき点):

  • Refactoring Guru: 視覚的な図解、多言語のコード例
  • GeeksforGeeks: 網羅的な解説、ユースケースの説明
  • GitHub (manwar/design-patterns): Perl/Moo(se)での実装例

弱み(差別化のポイント):

  • Perl/Moo特化の記事が極めて少ない: 日本語では皆無に近い
  • MooX::Cloneの解説が少ない: Moo向けのクローン実装の解説がない
  • 入門者向けの段階的解説がない: いきなりパターンの説明から始まる
  • 「動くモノを作る楽しさ」がない: 抽象的な例(動物、図形)が多い

7.3 差別化できるポイント

  1. 日本語でのPerl/Moo特化: 希少価値が高い
  2. 段階的な学習: 「問題発覚→パターンで解決」のストーリー
  3. 実践的な題材: 「動くモノを作る楽しさ」を重視
  4. MooX::Cloneの紹介: Moo向けの現代的な実装方法
  5. 浅いコピー/深いコピーの詳細解説: Perl特有の落とし穴を説明

信頼度: 9/10


8. 内部リンク候補

8.1 「Mooで覚えるオブジェクト指向プログラミング」シリーズ(全12回)

タイトル内部リンクPrototypeパターンとの関連
第1回Mooで覚えるオブジェクト指向プログラミング/2021/10/31/191008/OOPの基礎
第2回データとロジックをまとめよう/2025/12/30/163810/hassub
第3回同じものを何度も作れるように/2025/12/30/163811/new(コンストラクタ)★clone()の対比に使える
第6回別のオブジェクトを属性に持つ/2025/12/30/163814/オブジェクトのネスト(深いコピーの問題)
第10回継承しないで振る舞いを共有/2025/12/30/163818/Moo::Role(Cloneableロールの定義)

8.2 デザインパターン関連

ドキュメント内容関連度
/content/warehouse/design-patterns-overview.mdデザインパターン概要(GoF 23パターン分類)最高
/content/warehouse/design-patterns-research.mdGoF 23パターン調査
/content/warehouse/factory-method-pattern.mdFactory Methodパターン調査(生成パターンの比較)

8.3 Moo/オブジェクト指向関連

内容内部リンク関連度
よなべPerlでMooについて喋った/2016/02/21/150920/

9. 参考文献・リソースリスト

9.1 必読リソース

書籍

書籍名著者ISBN/ASIN重要度
Design Patterns: Elements of Reusable Object-Oriented SoftwareGoF978-0201633610必須
Head First Design Patterns (2nd Edition)Eric Freeman, Elisabeth Robson978-1492078005推奨
オブジェクト指向における再利用のためのデザインパターンGoF(日本語訳)4797311126推奨

Webリソース

リソース名URL特徴信頼度
Refactoring Guru - Prototypehttps://refactoring.guru/design-patterns/prototype視覚的な図解、多言語コード例★★★★★
Wikipedia - Prototype patternhttps://en.wikipedia.org/wiki/Prototype_pattern正式な定義★★★★★
GeeksforGeeks - Prototype Design Patternhttps://www.geeksforgeeks.org/system-design/prototype-design-pattern/網羅的な解説★★★★☆
MetaCPAN - MooX::Clonehttps://metacpan.org/pod/MooX::CloneMoo向けクローン実装★★★★★
MetaCPAN - Clonehttps://metacpan.org/pod/ClonePerl用クローン関数★★★★★
Perldoc - Storablehttps://perldoc.perl.org/Storable標準モジュール★★★★★
GitHub - manwar/design-patternshttps://github.com/manwar/design-patternsPerl/Mooでのパターン実装例★★★★☆
Effective Perl Programming - Make deep copieshttps://www.effectiveperlprogramming.com/2010/03/make-deep-copies/深いコピーの解説★★★★★

10. 調査結果のサマリー

10.1 主要な発見

  1. Prototypeパターンの位置づけ: GoFの生成パターンの1つ。既存オブジェクトをクローンして新しいオブジェクトを生成する

  2. 他の生成パターンとの違い:

    • Factory Method: newでインスタンス化、継承が必要
    • Prototype: clone()でコピー、継承不要
    • Singleton: 1つだけ保証
    • Prototype: 複数のコピーを生成
  3. Perl/Moo実装のポイント:

    • MooX::Cloneが最も簡単(useするだけでclone()が使える)
    • Storable::dclone()で深いコピーが可能
    • Clone::clone()も高速で便利
  4. 浅いコピー/深いコピー: Prototypeパターン実装で最も重要な考慮点。ネストしたオブジェクトの扱いに注意

  5. 既存シリーズとの重複なし: Prototypeパターンを扱う既存シリーズは存在しない

  6. 差別化ポイント: 日本語でのPerl/Moo特化記事は極めて希少

10.2 追加調査が検討できる領域

  1. MooX::Cloneの動作検証: 実際にコードで動作確認

  2. 深いネストを含むオブジェクトのテスト: MooX::Cloneがどこまで対応するか


調査完了日: 2026年1月13日 調査者: 調査・情報収集エージェント


End of Document

comments powered by Disqus
Hugo で構築されています。
テーマ StackJimmy によって設計されています。