home screen

Search



Number Of Result : 0

Result :


Thursday, November 27, 2008

Prototype Pattern - Clone 1 đối tượng theo DEEP và theo Shallow

- Problem : Tạo 1 bản sao theo chiều xâu, nếu ta dung hàm MemberwiseClone() Method thì chỉ là Shallow chính vì vậy ta phải tao thêm 1 Method để nó tạo bản sao 1 đối tượng theo Deep
- Ngữ cảnh A has-a B,A2 = A1.Clone()

- Khái niệm :
+ Shallow : có nghĩa là khi thây đổi Property's Value của lớp đối tượng B2 trong A2, thì nếu dùng hàm MemberwiseClone() Method, thì Property's Value của B1 trong A1 cũng sẽ thay đổi theo(vì nó còn giữ tham chiếu)
+ Deep : thay doi Property's Value của B2 trong A2, chỉ có nó bị thay đổi ko anh hưởng tới lớp đối tượng đã Clone ra nó( tức là Property's Value của B1 trong A1 ko thây đổi)
- Phải đặt [Serializable()] trước các lớp

[Serializable()]
public abstract class IPrototype<T>
{
public T Clone()
{
return (T)this.MemberwiseClone();
}

///
/// ĐÂY LÀ HÀM SẼ TẠO DEEP CLONE CỦA 1 ĐỐI TƯỢNG - TỨC LÀ THAY ĐỔI 1 DOI TUONG HAS-A 1 DOI TUONG KHÁC THÌ KO ẢNH HƯỞNG
/// ĐỐI TƯỢNG ĐÃ CLONE RA NÓ
///

///
public T DeepClone()
{
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
stream.Seek(0, SeekOrigin.Begin);
T copy = (T)formatter.Deserialize(stream);
stream.Close();
return copy;
}
}


- Lớp đối tượng được Has-a bởi 1 đối tượng khác

// Helper class used to create a second level data structure
[Serializable()]
public class DeeperData
{
public string Data { get; set; }
public DeeperData(string s)
{
Data = s;

}
public override string ToString()
{
return Data;
}
}




[Serializable()]
public class Prototype : IPrototype<Prototype>
{
// Content members
string Country { get; set; }
public string Capital { get; set; }
public DeeperData Language { get; set; }
public List list_deeper = new List();
public List list_String = new List();

public Prototype(string country, string capital, string language)
{
Country = country;
Capital = capital;
Language = new DeeperData(language);
list_deeper.Add ( new DeeperData(language) );
list_deeper.Add(new DeeperData(language));

list_String.Add(language);
list_String.Add(language);


}
public override string ToString()
{
return Country + "\t\t" + Capital + "\t\t->" + Language + "\n\t list - deeper : " + list_deeper[0] + "\t" +list_deeper[1]
+ "\n\t list - string: " + list_String[0] + "\t" + list_String[1];
}


}




[Serializable()]
public class PrototypeManager : IPrototype<Prototype>
{
public Dictionary prototypes
= new Dictionary {
{"Germany", new Prototype ("Germany", "Berlin", "German")},
{"Italy",new Prototype ("Italy", "Rome", "Italian")},
{"Australia", new Prototype ("Australia", "Canberra", "English")}
};


}



[Serializable()]
class PrototypeClient
{
static void Report(string s, Prototype a, Prototype b)
{
Console.WriteLine("\n" + s);
Console.WriteLine("Prototype : " + a + "\nClone : " + b);

}
static void Main()
{

PrototypeManager manager = new PrototypeManager();
Prototype c2, c3;

//1. SHALLOW

// Make a copy of Australia's data
c2 = manager.prototypes["Australia"].Clone();
Report("Shallow cloning Australia\n===============",
manager.prototypes["Australia"], c2);

// Change the capital of Australia to Sydney
c2.Capital = "Sydney";
Report("Altered Clone's shallow state, prototype unaffected",
manager.prototypes["Australia"], c2);

// Change the language of Australia (deep data)
c2.Language.Data = "Chinese";
c2.list_deeper[0].Data = "Ha Noi";
c2.list_String[0] = "Ha Noi";
Report("Altering Clone deep state: prototype affected *****",
manager.prototypes["Australia"], c2);


//2. DEEP

// Make a copy of Germany's data
c3 = manager.prototypes["Germany"].DeepClone();
Report("Deep cloning Germany\n============",
manager.prototypes["Germany"], c3);
// Change the capital of Germany
c3.Capital = "Munich";
Report("Altering Clone shallow state, prototype unaffected",
manager.prototypes["Germany"], c3);

// Change the language of Germany (deep data)
c3.Language.Data = "Turkish";
c3.list_deeper[0].Data = "Ha Noi";
Report("Altering Clone deep state, prototype unaffected", manager.prototypes["Germany"], c3);


}

}


Reference : C# 3.0 Design Patterns Ebook.

No comments: