2024. 10. 14. 05:35ㆍDesign Pattern
Prototype 패턴
Prototype 패턴은 생성 패턴(Creational Pattern) 중 하나로, 객체를 직접 생성하는 대신 이미 존재하는 객체를 복제하여 새로운 객체를 만드는 방법을 제공합니다.
이 패턴은 성능이 중요한 경우나 객체를 반복적으로 생성할 때 사용할 수 있습니다.
1. Prototype 패턴이란?
Prototype 패턴은 객체를 생성하는 데 필요한 복잡한 과정을 피하기 위해 기존 객체의 복제본을 만드는 방식입니다.
이를 통해 객체를 생성하는 데 필요한 시간을 절약할 수 있으며, 새로운 인스턴스를 만드는 대신 기존 객체를 복사하는 방식을 채택하여 유연성을 제공합니다.
언제 사용하는가?
- 객체 생성 비용이 클 때: 복잡한 초기 설정이나 많은 자원을 사용하는 객체의 경우, 복제하여 새로운 객체를 생성하는 것이 더 효율적입니다.
- 객체의 초기 설정이 반복될 때: 객체의 구성이 복잡하거나 반복적으로 생성해야 하는 경우 Prototype 패턴이 유용합니다.
2. Prototype 패턴의 구조
Prototype 패턴의 구조는 크게 Prototype 인터페이스와 ConcretePrototype 클래스로 나뉩니다.
Prototype 인터페이스
- Clone 메서드: 복제 기능을 정의하는 인터페이스로, 이 메서드를 통해 객체의 복제가 이루어집니다.
ConcretePrototype 클래스
- Clone 메서드 구현: Prototype 인터페이스를 구현한 실제 클래스입니다. 이 클래스는 복제 가능한 구체적인 객체로, 객체의 복제를 책임집니다.
3. Prototype 패턴의 구현 예시 (C#)
// Prototype 인터페이스
public abstract class Shape
{
public string Id { get; set; }
public abstract Shape Clone();
}
// ConcretePrototype 클래스
public class Circle : Shape
{
public int Radius { get; set; }
// Clone 메서드를 오버라이드하여 객체를 복제
public override Shape Clone()
{
return (Shape)this.MemberwiseClone(); // 얕은 복사
}
public override string ToString()
{
return $"Circle: Radius = {Radius}, Id = {Id}";
}
}
public class Rectangle : Shape
{
public int Width { get; set; }
public int Height { get; set; }
public override Shape Clone()
{
return (Shape)this.MemberwiseClone();
}
public override string ToString()
{
return $"Rectangle: Width = {Width}, Height = {Height}, Id = {Id}";
}
}
위 코드에서는 Shape 클래스가 Prototype 패턴을 구현하는 추상 클래스이며, Circle과 Rectangle 클래스는 그 구체적인 구현체들입니다. MemberwiseClone() 메서드를 사용하여 객체를 얕게 복사합니다.
클라이언트 코드
public class Program
{
public static void Main(string[] args)
{
Circle circle1 = new Circle { Radius = 10, Id = "1" };
Circle circle2 = (Circle)circle1.Clone(); // Circle 객체 복제
circle2.Id = "2";
circle2.Radius = 20;
Console.WriteLine(circle1); // Circle: Radius = 10, Id = 1
Console.WriteLine(circle2); // Circle: Radius = 20, Id = 2
Rectangle rect1 = new Rectangle { Width = 5, Height = 10, Id = "3" };
Rectangle rect2 = (Rectangle)rect1.Clone();
rect2.Id = "4";
rect2.Width = 15;
Console.WriteLine(rect1); // Rectangle: Width = 5, Height = 10, Id = 3
Console.WriteLine(rect2); // Rectangle: Width = 15, Height = 10, Id = 4
}
}
위 예시에서는 Circle과 Rectangle 객체를 각각 복제하여 새 객체를 만들고, 새롭게 복제된 객체의 속성을 변경해도 원본 객체에는 영향을 미치지 않음을 보여줍니다.
4. 깊은 복사 vs 얕은 복사
Prototype 패턴에서 복제 방식은 크게 깊은 복사(Deep Copy)와 얕은 복사(Shallow Copy)로 나뉩니다.
- 얕은 복사(Shallow Copy): 객체의 참조만 복사하는 방식으로, 원본 객체와 복제된 객체가 같은 참조 객체를 공유합니다. MemberwiseClone()이 얕은 복사를 수행합니다.
- 깊은 복사(Deep Copy): 객체의 참조뿐 아니라 그 내부에 있는 모든 객체까지 새롭게 복사하는 방식입니다. 깊은 복사는 일반적으로 더 복잡하며, 모든 하위 객체까지 복제해야 합니다.
5. Prototype 패턴의 장단점
장점:
- 복잡한 객체 생성 비용 절감: 객체를 처음부터 생성하는 비용을 줄이고, 객체를 빠르게 복제할 수 있습니다.
- 유연성: 객체의 복제본을 쉽게 만들 수 있어 코드 재사용성이 높아지고, 다양한 형태의 객체를 빠르게 생성할 수 있습니다.
단점:
- 깊은 복사 구현의 복잡성: 깊은 복사를 구현하려면 객체의 모든 필드와 하위 객체를 수동으로 복제해야 하므로 코드가 복잡해질 수 있습니다.
- 복제 과정에서 오류 발생 가능성: 객체가 복잡해질수록 복제 과정에서의 오류 가능성이 커질 수 있습니다. 특히 복제된 객체가 원본 객체와 예상치 못한 참조를 공유하는 경우 문제가 발생할 수 있습니다.
6. Prototype 패턴의 사용 사례
6.1. 게임 개발
게임 개발에서는 다양한 캐릭터, 무기, 아이템을 효율적으로 생성하기 위해 Prototype 패턴이 자주 사용됩니다.
기본 템플릿을 복제하여 새로운 아이템이나 캐릭터를 빠르게 만들 수 있습니다.
6.2. 문서 편집기
문서 편집기에서 여러 종류의 서식이 적용된 문서를 빠르게 생성할 때, Prototype 패턴을 사용하여 기본 서식을 복제하여 새로운 문서를 생성할 수 있습니다.
Prototype 패턴은 객체를 새로 생성하는 대신 복제하여 필요한 객체를 효율적으로 생성할 수 있는 패턴입니다.
성능과 메모리 관리 측면에서 유리하며, 객체를 복잡하게 생성하는 대신 복제하여 빠르게 사용할 수 있습니다. 깊은 복사와 얕은 복사에 대한 이해를 바탕으로 적절한 상황에서 이 패턴을 적용하면 성능 향상과 코드 유연성을 얻을 수 있습니다.
'Design Pattern' 카테고리의 다른 글
프록시(Proxy) 패턴 (0) | 2024.10.17 |
---|---|
컴포지트(Composite) 패턴 (0) | 2024.10.17 |
DI (Dependency Injection) 및 IoC (Inversion of Control) 패턴 (0) | 2024.10.14 |
MVVM (Model-View-ViewModel) 패턴 (2) | 2024.10.14 |
MVC (Model-View-Controller) 패턴 (1) | 2024.10.14 |