Prototype パターン

Prototype パターンとは、ソフトウェア開発で用いられる、生成に関するデザインパターンの1つである。生成されるオブジェクトの種別がプロトタイプ的なインスタンスであるときに使用され、このプロトタイプを複製して新しいオブジェクトを生成する。

このパターンは

Abstract Factory パターンでなされるように、クライアント・アプリケーションにおいてオブジェクトの生成者をサブクラスにすることを回避する
標準的な方法で新しいオブジェクトを作ることによる固有のコストが所与のアプリケーションにとって高すぎる時にそれを回避するために用いられる。

このパターンを実装するには、純粋仮想pure virtual method}}の //clone//メソッドを指定する抽象的な基底クラスを宣言する。「多態性を持つコンストラクタ」の能力を必要とする全てのクラスは抽象的な基底クラスから自身を派生させ、//clone//の操作を実装する。

クライアントは、ハードコードされたクラス名において"new"演算子を呼び出すコードを書く代わりに、プロトタイプにおいて//clone//メソッドを呼び出すか、所望の特定の具体的な派生クラスを指し示すパラメタを渡してファクトリメソッドを呼び出すか、//clone//メソッドを他のデザインパターンにより供給される何らかの機構を通じて呼び出すかする。

1. 例
----

Prototypeパターンではプロトタイプとなるインスタンスを用いて作成するオブジェクトの種別を指定する。本格的に生成を行う前に新しい生成物のプロトタイプが作られる場合も多いが、ここに挙げる例においてはプロトタイプは受動的なものであり自身の複製には関与しない。2つの同一の細胞が得られる有糸分裂は自己複製において能動的な役割を演じるプロトタイプの一例であり、よってPrototypeパターンの例示となる。細胞が分裂すると、同一の遺伝子型を持つ2つの細胞となる。言い換えれば、細胞はそれ自身を複製するのである。

1.1. Java
---------

/

Prototype Class
/abstract class PrototypeFactory implements Cloneable { public Object clone throws CloneNotSupportedException { // call Object.clone PrototypeFactory copy =  super.clone; //In an actual implementation of this pattern you might now change references to //the expensive to produce parts from the copies that are held inside the prototype. return copy; }

abstract void prototypeFactory;

abstract void printValue; }

/

Concrete Prototypes to clone
/class PrototypeImpl extends PrototypeFactory { int x;

public PrototypeImpl { this.x = x; }

@Override void prototypeFactory { this.x = x; }

public void printValue { System.out.println; } }

/

Client Class
/public class PrototypeExample {

private PrototypeFactory example; // Could have been a private Cloneable example.

public PrototypeExample { this.example = example; }

public PrototypeFactory makeCopy throws CloneNotSupportedException { return  this.example.clone; }

public static void main { try { PrototypeFactory tempExample = null; int num = 1000; PrototypeFactory prot = new PrototypeImpl; PrototypeExample cm = new PrototypeExample; for  { tempExample = cm.makeCopy; tempExample.prototypeFactory; tempExample.printValue; } } catch  { e.printStackTrace; } } }

/*

Code outputValue :0 Value :1000 Value :2000 Value :3000 Value :4000 Value :5000 Value :6000 Value :7000 Value :8000 Value :9000

/<WtXmlEndTag />

2. 経験則
------

生成に関するパターン同士には重なる部分があることもある――PrototypeパターンとAbstract Factory パターンのどちらも適切となるような場合もある。また両者が相補的な関係となる場合もある。Abstract Factoryは複製元となる一群のプロトタイプを蓄えておき、生成したオブジェクトを返すようにできる。Abstract Factory、Builder、Prototypeの各パターンは実装の際にSingleton パターンを利用できる。Abstract Factoryのクラスはファクトリメソッドを伴い実装される場合が多いが、プロトタイプを用いるように実装することもできる。

デザインはしばしば、比較的に複雑でなく、カスタマイズしやすく、サブクラスを急速に増やすファクトリメソッドを用いるところから出発し、一層の柔軟性が必要となる箇所が発見されるに伴いより柔軟だが複雑なAbstract Factory、Prototype、Builderへと発達してゆく。

プロトタイプはサブクラスの生成を必要としないが、「初期化」の操作を必要とする。ファクトリメソッドはサブクラスの生成を必要とするが、初期化を必要としない。

Composite パターンとDecorator パターンを多用するデザインにおいてもPrototypeパターンはしばしば有用である。

複製しようとしているオブジェクトの「真正なコピー」である別のオブジェクトを「ランタイムに」生成したい場合には、オブジェクトをcloneする必要があるであろうというのが経験則である。「真正なコピー」というのは、新規作成されるオブジェクトの全ての属性が複製しようとしているオブジェクトと同一でなければならないという意味である。代わりに//new//を用いてクラスから「インスタンス作成」したならば、全ての属性がその初期値となったオブジェクトが得られる。

例えば、銀行口座の取引を行うシステムをデザインしているとすると、口座の情報を保持しているオブジェクトのコピーを作成し、そのコピーに取引を実施し、それからこのコピーで元のオブジェクトを置き換える必要があるであろう。このような場合には、newの代わりにcloneを用いたいであろう。

3. 脚注
-----

4. 参考文献
-------

author=Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John

エリック・ガンマ、ラルフ・ジョンソン、リチャード・ヘルム、ジョン・ブリシディース、グラディ・ブーチ、本位田真一、吉田和樹、『オブジェクト指向における再利用のためのデザインパターン』、ソフトバンクパブリッシング、1995年。ISBN 978-4797311129

5. 関連項目
-------

関数プロトタイプ

6. 外部リンク
--------

[1] in Source Making
[2] - JavaTM Platform Standard Ed. 6