프로토타입은 클래스에 의존하지 않고 기존 객체들을 복사할 수 있도록 하는 생성 디자인 패턴이다.
객체를 생성한 뒤, 해당 객체와 완전히 동일한 복사본을 만들고자 한다면 어떤 방식이 있을까? 지금까지는 new 키워드와 함께 새로운 인스턴스를 생성한 뒤, 객체의 필드값을 신규 인스턴스에 넣어줬을 것이다. 하지만 이 경우 복사하고자 하는 객체의 클래스를 알아야한다는 것과, 알더라도 비공개 필드에는 접근하지 못한다는 문제가 생긴다. 이때 프로토타입 패턴은 객체들에게 복제 프로세스를 위임하여 클래스의 접근 없이 객체로부터 복제하는 것이 가능해진다.
Clone
프로토타입 패턴에서는 복제를 지원하는 객체마다 공통된 인터페이스를 상속받는데, 일반적으로 Clone 메서드만 포함하는 인터페이스를 구현함으로써 객체로부터 복제가 가능한 것이다.
public interface ProtoType
{
public abstract object Clone();
}
ProtoType 인터페이스를 상속받는 클래스에서의 구현은 크게 다르지 않다. 클래스의 객체를 만든 후에 이전 객체의 모든 필드값을 신규 객체로 전달하도록 구현하면 되는 것이다. 이 경우 클래스 내부의 private 필드의 접근이 가능하기에, 완전한 복제본을 얻는 것이 가능하다.
public class Monster : ProtoType
{
private int Hp;
public string Name;
public int Level { get; private set; }
public Monster(string name, int hp, int level)
{
this.Name = name;
this.Hp = hp;
this.Level = level;
}
public Monster(Monster monster)
{
this.Name = monster.Name;
this.Hp = monster.Hp;
this.Level = monster.Level;
}
public object Clone()
{
Monster monster = new Monster(this);
return monster;
}
}
static void Main(string[] args)
{
Monster monster = new Monster("슬라임", 50, 3);
Monster monster0 = monster.Clone() as Monster;
Console.WriteLine($"이름 : {monster0.Name}, 레벨 : {monster0.Level}, 체력 : {monster0.Hp}");
Console.WriteLine($"객체 타입 : {monster0.GetType()}");
}
이름 : 슬라임, 레벨 : 3, 체력 : 50
객체 타입 : Program+Monster
monster0
는 monster
를 복제한 프로토타입으로 실제로 monster의 필드값과 동일한 것을 확인할 수 있다.