
_START_ARTICLE_
Prototype パターン
_START_SECTION_
例
_START_PARAGRAPH_
Prototypeパターンではプロトタイプとなるインスタンスを用いて作成するオブジェクトの種別を指定する。本格的に生成を行う前に新しい生成物のプロトタイプが作られる場合も多いが、ここに挙げる例においてはプロトタイプは受動的なものであり自身の複製には関与しない。2つの同一の細胞が得られる有糸分裂は自己複製において能動的な役割を演じるプロトタイプの一例であり、よってPrototypeパターンの例示となる。細胞が分裂すると、同一の遺伝子型を持つ2つの細胞となる。言い換えれば、細胞はそれ自身を複製するのである。
_START_SECTION_
Java
_START_PARAGRAPH_
/** * Prototype Class */abstract class PrototypeFactory implements Cloneable {_NEWLINE_    public Object clone() throws CloneNotSupportedException {_NEWLINE_        // call Object.clone()_NEWLINE_        PrototypeFactory copy = (PrototypeFactory) super.clone();_NEWLINE_        //In an actual implementation of this pattern you might now change references to_NEWLINE_        //the expensive to produce parts from the copies that are held inside the prototype._NEWLINE_        return copy;_NEWLINE_    }_NEWLINE__NEWLINE_    abstract void prototypeFactory(int x);_NEWLINE__NEWLINE_    abstract void printValue();}/** * Concrete Prototypes to clone */class PrototypeImpl extends PrototypeFactory {_NEWLINE_    int x;_NEWLINE__NEWLINE_    public PrototypeImpl(int x) {_NEWLINE_        this.x = x;_NEWLINE_    }_NEWLINE__NEWLINE_    @Override_NEWLINE_    void prototypeFactory(int x) {_NEWLINE_        this.x = x;_NEWLINE_    }_NEWLINE__NEWLINE_    public void printValue() {_NEWLINE_        System.out.println("Value :" + x);_NEWLINE_    }}/** * Client Class */public class PrototypeExample {_NEWLINE__NEWLINE_    private PrototypeFactory example; // Could have been a private Cloneable example._NEWLINE__NEWLINE_    public PrototypeExample(PrototypeFactory example) {_NEWLINE_        this.example = example;_NEWLINE_    }_NEWLINE__NEWLINE_    public PrototypeFactory makeCopy() throws CloneNotSupportedException {_NEWLINE_        return (PrototypeFactory) this.example.clone();_NEWLINE_    }_NEWLINE__NEWLINE_    public static void main(String args[]) {_NEWLINE_        try {_NEWLINE_            PrototypeFactory tempExample = null;_NEWLINE_            int num = 1000;_NEWLINE_            PrototypeFactory prot = new PrototypeImpl(1000);_NEWLINE_            PrototypeExample cm = new PrototypeExample(prot);_NEWLINE_            for (int i = 0; i < 10; i++) {_NEWLINE_                tempExample = cm.makeCopy();_NEWLINE_                tempExample.prototypeFactory(i * num);_NEWLINE_                tempExample.printValue();_NEWLINE_            }_NEWLINE_        } catch (CloneNotSupportedException e) {_NEWLINE_            e.printStackTrace();_NEWLINE_        }_NEWLINE_    }}/***Code output**Value :0Value :1000Value :2000Value :3000Value :4000Value :5000Value :6000Value :7000Value :8000Value :9000*/
_START_SECTION_
経験則
_START_PARAGRAPH_
生成に関するパターン同士には重なる部分があることもある――PrototypeパターンとAbstract Factory パターンのどちらも適切となるような場合もある。また両者が相補的な関係となる場合もある。Abstract Factoryは複製元となる一群のプロトタイプを蓄えておき、生成したオブジェクトを返すようにできる。Abstract Factory、Builder、Prototypeの各パターンは実装の際にSingleton パターンを利用できる。Abstract Factoryのクラスはファクトリメソッド（継承を通す作成）を伴い実装される場合が多いが、プロトタイプ（委譲を通す作成）を用いるように実装することもできる。_NEWLINE_デザインはしばしば、比較的に複雑でなく、カスタマイズしやすく、サブクラスを急速に増やすファクトリメソッドを用いるところから出発し、一層の柔軟性が必要となる箇所が発見されるに伴いより柔軟だが複雑なAbstract Factory、Prototype、Builderへと発達してゆく。_NEWLINE_プロトタイプはサブクラスの生成を必要としないが、「初期化」の操作を必要とする。ファクトリメソッドはサブクラスの生成を必要とするが、初期化を必要としない。_NEWLINE_Composite パターンとDecorator パターンを多用するデザインにおいてもPrototypeパターンはしばしば有用である。_NEWLINE_複製しようとしているオブジェクトの「真正なコピー」である別のオブジェクトを「ランタイムに」生成したい場合には、オブジェクトをclone()する必要があるであろうというのが経験則である。「真正なコピー」（True copy）というのは、新規作成されるオブジェクトの全ての属性が複製しようとしているオブジェクトと同一でなければならないという意味である。代わりにnewを用いてクラスから「インスタンス作成」したならば、全ての属性がその初期値となったオブジェクトが得られる。_NEWLINE_例えば、銀行口座の取引を行うシステムをデザインしているとすると、口座の情報を保持しているオブジェクトのコピーを作成し、そのコピーに取引を実施し、それからこのコピーで元のオブジェクトを置き換える必要があるであろう。このような場合には、newの代わりにclone()を用いたいであろう。