Day 7 – Prototype Pattern

프로토타입 패턴은 객체를 만드는 데 비용이 많이 들거나 복잡할 때 기존 객체를 복제하여 새로운 객체를 만드는 데 사용되는 생성적 디자인 패턴입니다. C#에서는 ICloneable 인터페이스를 통해 이 패턴을 구현할 수 있습니다.


얕은 복사 (Shallow Copy)

얕은 복사는 C#에서 개체를 복사하는 방법 중 하나입니다. 객체의 필드를 새 객체에 복사하지만 해당 필드가 참조 유형인 경우 참조된 객체 자체는 복사하지 않고 참조만 복사합니다. 즉, 원본 개체와 복제된 개체는 동일한 참조 유형의 데이터를 공유합니다. 이는 값 유형 필드의 경우 비트 단위로 복사가 이루어지지만 참조 유형 필드의 경우 객체의 주소만 복사되기 때문입니다.

깊은 복사 (Deep Copy)

객체에 참조 유형의 필드가 포함된 경우 프로토타입 패턴에서 전체 복사를 구현하는 것이 중요합니다. 전체 복사는 객체의 모든 필드를 복제할 뿐만 아니라 참조 유형 필드가 가리키는 객체를 재귀적으로 복제합니다. 이렇게 하면 원본 개체와 복제된 개체 사이에 공유 참조가 없으므로 한 개체를 수정해도 다른 개체에 영향을 주지 않습니다.


Code

ShallowPerson.cs
public class ShallowPerson : ICloneable
{
    public string? Name { get; set; }
    public Address Address { get; set; } = new();
    public object Clone()
    {
        return this.MemberwiseClone();
    }
}
C#
Address.cs
public class Address
{
    public string? StreetName { get; set; }
    public int HouseNumber { get; set; }
}
C#
DeepPerson.cs
public class DeepPerson : ICloneable
{
    public string? Name { get; set; }
    public Address Address { get; set; } = new();
    public object Clone()
    {
        var serialized = System.Text.Json.JsonSerializer.Serialize(this);
        return System.Text.Json.JsonSerializer.Deserialize<DeepPerson>(serialized)!;
    }
}
C#
Program.cs

//**************************
// Shallow Copy
//**************************
Console.WriteLine();
Console.WriteLine("Shallow Copy");

ShallowPerson shallowOriginal = new ShallowPerson();
shallowOriginal.Name = "Name";
shallowOriginal.Address.StreetName = "Street 1";

ShallowPerson shallowClone = (ShallowPerson)shallowOriginal.Clone();
Console.WriteLine("==> Before Changed. Original: {0}, Clone: {1}", shallowOriginal.Address.StreetName, shallowClone.Address.StreetName);
shallowClone.Address.StreetName = "Street 2";
Console.WriteLine("==> After Changed.  Original: {0}, Clone: {1}", shallowOriginal.Address.StreetName, shallowClone.Address.StreetName);

//**************************
// Deop Copy
//**************************
Console.WriteLine();
Console.WriteLine("Deop Copy");

DeepPerson deepOriginal = new DeepPerson();
deepOriginal.Name = "Name";
deepOriginal.Address.StreetName = "Street 1";

DeepPerson deepClone = (DeepPerson)deepOriginal.Clone();
Console.WriteLine("==> Before Changed. Original: {0}, Clone: {1}", deepOriginal.Address.StreetName, deepClone.Address.StreetName);
deepClone.Address.StreetName = "Street 2";
Console.WriteLine("==> After Changed.  Original: {0}, Clone: {1}", deepOriginal.Address.StreetName, deepClone.Address.StreetName);

C#

요약

깊은 복사와 얕은 복사는 다양한 상황에 적합합니다.

얕은 복사 (Shallow Copy)

  • 객체에 참조 유형의 필드가 포함되어 있지 않거나 참조 유형의 필드가 변경 불가능한 경우.
  • 객체의 참조 유형 필드를 공유할 수 있고 이는 문제가 되지 않습니다.
  • 성능이 중요하고 전체 복사로 인한 오버헤드를 피하고 싶은 경우.

깊은 복사 (Deep Copy)

  • 개체의 전체 복사본이 필요하고 참조 공유의 부작용을 피하고 싶은 경우.
  • 객체에 참조 유형의 필드가 포함되어 있고 복사본이 원본과 독립적이어야 하는 경우.
  • 원본에 영향을 주지 않고 복사본에서 참조 유형의 데이터를 변경할 때.

Links

Comments

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다