GoFの説明にあった(らしい)クラス図
Prototypeパターン クラス図
オブジェクト生成に関するデザインパターンの一種。
一般にはオブジェクトのクローニングでインスタンスを複製することに説明の重点があるように見えて、あまり頻繁には使われないパターンではないかと思っていた。
Factory Methodパターンと同様に__具象的クラスをクラス使用者から隠蔽できる__というのが特徴の一つで、Factory Methodとはどう差別化されるのかを考えると
- Factory Methodは一つのオブジェクトを定義するのに生成用(Factory)と操作用(Product)の二つの抽象クラス(インターフェイス)が必要
- Prototypeは一つのオブジェクトを定義するのにそのオブジェクトのための抽象クラス(インターフェイス)一つでよい。
- Factory Methodではオブジェクト生成メソッドが具象的だったり、複数あっても問題ない。
むしろそのオブジェクトごとに特化したものの方が使いやすい。 - Prototypeではオブジェクト生成メソッドはclone()のような共通した単純なものの方が使いやすい。
あってもいいが、「オブジェクトの複製を作り、少ないコストで別インスタンスとして仕立てる」ような使い勝手の良さを損ないそう。
手習いのためにC#でコード作成。この程度ならJavaとそうかわらないはずなのに、慣れていないせいか書き心地悪かったなぁ。
追記:kobitoだとcs, c#でハイライトつくようだけど、Webだとcsharpかc#らしい。orz
Prototype.cs
using System;
namespace Prototype
{
abstract class MyObject
{
static MyObject()
{
MyObject.Default = new MyObjectLogged();
}
protected MyObject(string name)
{
this.Name = name;
}
public MyObject clone()
{
MyObject instance;
instance = (MyObject) MyObject.Default.MemberwiseClone();
return instance;
}
public static MyObject Default { get; protected set; }
public string Name { get; set; }
abstract public void DisplayName();
}
class MyObjectLogged : MyObject
{
protected internal MyObjectLogged()
: base("default-object")
{
Console.WriteLine("-- MyObjectLogged created.");
}
public override void DisplayName()
{
Console.WriteLine("-- start DisplayName()");
Console.WriteLine("this object name = {0:s}", this.Name);
Console.WriteLine("-- end DisplayName()");
}
}
class Program
{
public static void Main(string[] args)
{
var o1 = MyObject.Default.clone();
o1.DisplayName();
var o2 = o1.clone();
o2.Name = "o1";
o2.DisplayName();
var o3 = o1.clone();
o3.Name = "o2";
o3.DisplayName();
o1.DisplayName();
}
}
}