デザインパターン Prototype:コピーしてインスタンスを作る
概要
クラスをnewしてインスタンスを作成せず、
インスタンスをコピーしてインスタンスを作成するパターン
クラス図
フレームワーク側
Prototype(原型)
public abstract void use(String s);
public abstract IProduct createClone();
}
Cloneableを継承したクラス(サブクラス)において、
clone()が実行されるとそのクラスのインスタンスがコピーされる
※本例ではMessageBox、UnderLinePenクラスにおけるcreateClone()メソッド実行時
Client(利用者)
private HashMap<String, IProduct> showcase = new HashMap<String, IProduct>();
public void register(String name, IProduct proto) {
IProductのインスタンスをKey毎に保持
this.showcase.put(name, proto);
}
public IProduct create(String protoname) {
指定KeyのIProductのインスタンスを取り出し
IProduct p = (IProduct)showcase.get(protoname);
指定KeyのIProductインスタンスを複製
return p.createClone();
実例ではMessageBox、UnderLinePenクラスのインスタンスが複製される
このクラス内にMessageBox、UnderLinePenというクラス名はハードコーディンされておらず再利用性が高い
}
}
具象側
ConcretePrototype(具体的な原型)
private char decochar;
public MessageBox(char decochar) {
this.decochar = decochar;
}
@Override
public void use(String s) {
int length = s.getBytes().length;
for (int i = 0; i < length + 4; i++) {
System.out.print(this.decochar);
}
System.out.println("");
System.out.println(this.decochar + " " + s + " " + this.decochar);
for (int i = 0; i < length + 4; i++) {
System.out.print(this.decochar);
}
System.out.println("");
}
@Override
public IProduct createClone() {
IProduct p = null;
try {
p = (IProduct)clone();
} catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
public class UnderLinePen implements IProduct {
private char ulchar;
public UnderLinePen(char ulchar) {
this.ulchar = ulchar;
}
@Override
public void use(String s) {
int length = s.getBytes().length;
System.out.println("\"" + s + "\"");
for (int i = 0; i < length; i++) {
System.out.print(this.ulchar);
}
System.out.println("");
}
@Override
public IProduct createClone() {
IProduct p = null;
try {
p = (IProduct)clone();
} catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
利用
public static void main(String[] args) {
Manager manager = new Manager();
UnderLinePen pen = new UnderLinePen('~');
MessageBox mbox = new MessageBox('*');
MessageBox sbox = new MessageBox('/');
manager.register("strong message", pen);
manager.register("warning box", mbox);
manager.register("slash box", sbox);
IProduct p1 = manager.create("strong message");
p1.use("Hello, world.");
IProduct p2 = manager.create("warning box");
p2.use("Hello, world.");
IProduct p3 = manager.create("slash box");
p3.use("Hello, world.");
}
}
結果
"Hello, world."
~~~~~~~~~~~~~
*****************
* Hello, world. *
*****************
/////////////////
/ Hello, world. /
/////////////////