デザインパターン Prototype:コピーしてインスタンスを作る

概要

クラスをnewしてインスタンスを作成せず、
インスタンスをコピーしてインスタンスを作成するパターン

クラス図


フレームワーク側

Prototype(原型)

public interface IProduct extends Cloneable {
 public abstract void use(String s);
 public abstract IProduct createClone();
}

Cloneableを継承したクラス(サブクラス)において、
clone()が実行されるとそのクラスのインスタンスがコピーされる
※本例ではMessageBox、UnderLinePenクラスにおけるcreateClone()メソッド実行時

Client(利用者)

public class Manager {
 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(具体的な原型)

public class MessageBox implements IProduct {

 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 class Program {
 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. /
/////////////////

コメントを残す

メールアドレスが公開されることはありません。