[Prototype] という英単語は, [原型], [模範] を意味する.
java では, 複製を作る操作を [Object] クラスが提供する [clone] メソッドを利用して行う. 通常は, [クラス] から [オブジェクト] を作成とう手順 (new を用いて) となるが, このパターンにおいては:
[オブジェクト] から [オブジェクト] (複製) を作成する.
[ConcretePrototype] が実装しているオブジェクト複製メソッドを利用して, 新しいオブジェクトを返す.
オブジェクト複製メソッドのインタフェースを定義する. 上記メソッドを [ConcretePrototype] で実装する際に [clone()] メソッドを使用する場合は, [Prototype] に [Cloneable] インタフェースを実装させる.
自身のオブジェクトを複製するメソッドを実装する.
[Prototype] パターンを適用したクラスを利用し処理する.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import java.util.Map;
import java.util.HashMap;
public class Client{
private Map<String, Prototype> hashmap = new HashMap<String, Prototype>();
public void regist(String key, Prototype prototype){
hashmap.put(key, prototype);
}
public Prototype create(String key){
Prototype prototype = hashmap.get(key);
return prototype.createClone();
}
}
|
1 2 3 4 5 6 7 8 | /*
clone メソッドを使用したい場合, そのスーパークラス•インタフェースのどこで
Cloneable インタフェースを実装していないといけない.
Cloneable インタフェースには抽象メソッドが一つも定義されていない. 単にそのクラスが clone できるかどうかのマーク付けをしているだけ.
*/
public abstract class Prototype implements Cloneable{
public abstract Prototype createClone();
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class ConcretePrototype extends Prototype{
private int id;
public ConcretePrototype(int id){
this.id = id;
}
public Prototype createClone(){
ConcretePrototype concretePrototype = null;
try{
concretePrototype = (ConcretePrototype)this.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return concretePrototype;
}
public int getId(){
return id;
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public class PrototypeUser{
public static void main(String[] args){
Client client = new Client();
ConcretePrototype cp1 = new ConcretePrototype(0);
ConcretePrototype cp2 = new ConcretePrototype(1);
ConcretePrototype cp3 = new ConcretePrototype(2);
client.regist("0", cp1);
client.regist("1", cp2);
client.regist("2", cp3);
Prototype prototype1 = client.create("0");
Prototype prototype2 = client.create("1");
Prototype prototype3 = client.create("2");
System.out.println(((ConcretePrototype)prototype1).getId());
System.out.println(((ConcretePrototype)prototype2).getId());
System.out.println(((ConcretePrototype)prototype3).getId());
}
}
|
上記のプログラムの実行結果:
[wtopia Prototype]$ java PrototypeUser
0
1
2
オブジェクトの生成方法としては以下の様々な方法がある.
一番ポピュラーな生成方法:
String str = new String();
java.lang.Object オブジェクトが定義している clone メソッドを使用して自身のコピーを生成する.
注意:
clone メソッドを使用したい場合, Cloneable インタフェースを実装しておく必要がある. コンストラクタは呼ばれない.
例としては:
class A implements Cloneable{
public Object copy(){
A a = null;
try{
a = (A)clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return a;
}
}
java.lang.Class オブジェクトが定義している newInstance メソッドを使用して, 生成する.
注意:
[InstantiationException], [IllegalAccessException] を例外として投げるので, 例外処理をしておく必要がある.
引数なしコンストラクタ (デフォルト) が呼ばれる.
完全修飾クラス名を元にオブジェクトを生成する:
A a = (A)Class.forName("A").newInstance();
既に生成しているオブジェクトを元にオブジェクトを生成する:
A a = new A();
A b = a.getClass().newInstance();