【デザインパターン】【GoF】【C#】プロトタイプ(Prototype)パターン

Prototype

 * 現在のインスタンスをまるごとクローン(コピー)を作成する
  (単純なnewでは、属性値が初期値に戻ってしまう)

注意

.NETやJavaでは、以下のように実装するが、これらは、浅いコピー(後述)であることに注意

■.NETの場合

 →ICloneableインタフェースを通じてMemberwiseClone()で実現

javaの場合

 →Cloneableインターフェースとclone()で実現 (以下の関連記事を参照のこと)
http://blogs.yahoo.co.jp/dk521123/34290445.html

浅いコピーと深いコピー

例1:浅いコピー(shallow copy

 * オブジェクトだけの複製する
  →オブジェクトのメンバ変数は複製される
  →ただし、オブジェクトの中でオブジェクトは複製される訳じゃない★注目★
  (オブジェクトのアドレスのコピーなので、クローン側を変更したら、クローン元も変更されてしまう。
   サンプルを参照のこと)

深いコピー(deep copy

 * オブジェクトから参照されるオブジェクトも含めたコピーを作成する

サンプル

浅いコピー

Person.cs

public class Person : ICloneable
{
    public string Id { get; set; }
    public string c{ get; set; }
    public int Year { get; set; }
    public Work Job { get; set; }
    public Person Partner { get; set; }

    public object Clone()
    {
        return this.MemberwiseClone();
    }
}

Work.cs

public class Work
{
    public string WorkId { get; set; }
    public string WorkName { get; set; }
}

Form1.cs

private void button1_Click(object sender, EventArgs e)
{
    Person someone = new Person()
   {
         Id = "M0001", Name = "Tom", Year = 25,
         Job = new Work() { WorkId = "W0001", WorkName = "Programmer", },
         Partner = new Person() { Id = "F0001", Name = "Lui", Year = 38, },
   };
   
   Person cloneone = (Person)someone.Clone();

   // 変更1
   cloneone.Age = 25;
   // 変更2
   cloneone.Job.WorkId = "W9999";
   cloneone.Job.WorkName = "FreeMan";
   // 変更3
   cloneone.Partner.Id = "F0002";
   cloneone.Partner.Name = "Mary";
   cloneone.Partner.Age = 21;

   // 変更1結果
   if (cloneone.Age == someone.Age)
   {
       this.Label1.Text = "変えたのにー";
   }
   else
   {
       this.Label1.Text = "変わってます"; // こっちが実行される
   }

   // 変更2結果
   if (cloneone.Job.WorkId == someone.Job.WorkId)
   {
       this.Label2.Text = "変えたのにー"; // こっちが実行される(浅いコピーだから)
   }
   else
   {
       this.Label2.Text = "変わってます";
   }

   // 変更3結果
   if (cloneone.Partner.Id == someone.Partner.Id)
   {
       this.Label3.Text = "変えたのにー"; // こっちが実行される(浅いコピーだから)
   }
   else
   {
       this.Label3.Text = "変わってます";
   }
}



関連記事

デザインパターンの分類 ~目次~

http://blogs.yahoo.co.jp/dk521123/32973303.html

Java】プロトタイプ(Prototype)パターン / Cloneableインターフェース

http://blogs.yahoo.co.jp/dk521123/34290445.html