1. 프로토타입 패턴이란?
- 어떤 객체에 대한 프로토타입을 만들어 놓고 그것을 복사해서 사용하는 패턴
- Clone을 이용하여 객체를 생성하는 방법
- 본래의 오브젝트의 복사본을 만들어 각 객체에 따라 데이터를 수정해주는 방식으로 오브젝트를 생성
- 기존에 생성된 객체를 이용하여 해당 타입의 객체를 생성
- 생성할 객체들의 타입이 프로토타입인 인스턴스로부터 결정, 인스턴스는 새 객체를 만들기 위해 자기 자신을 복제
- 유니티에서는 Instantiate()가 같은 역할을 하도록 구현되어 있음.
- 객체들을 그의 특정 클래스들에 결합하지 않고 복제할 수 있도록 하는 생성 디자인 패턴
2. 프로토타입 패턴을 사용하는 경우
- 비슷한 오브젝트를 지속적으로 생성해야 할 경우
- 클래스로부터 인스턴스 생성이 어려운 경우
- Framework와 생성하는 인스턴스를 분리하고 싶은 경우
- 종류가 너무 많아서 클래스로 정리할 수 없는 경우
3. 프로토타입 패턴의 장점
1) 추상화 : 객체를 만드는 복잡한 과정을 숨길 수 있음.
2) 효율성 : 기존 객체를 복제하는 과정이 새 인스턴스를 만드는 것보다 비용면에서 효율적일 수 있음.
3) 유연성 : clone에서 반환하는 타입이 clone을 정의한 클래스와 반드시 동일할 필요는 없다. 즉 클래스의 계층 구조가 있을 때 추상화된 타입을 반환할 수 있는 유연성이 있음.
4. 프로토타입 패턴의 단점
1) 구현의 복잡성 : 인스턴스를 복제하는 과정 자체가 복잡할 수 있음.
2) 적용의 어려움 : 복제과정을 통해 객체를 생성하는 것이 어려운 경우 적용하기 어려움
5. 코드 구현
- IExercise라는 인터페이스를 통해 얕은 복사 함수들을 정의해주고, 각 클래스마다 이를 재정의하여 사용한다.
- 최초 생성되는 fit라는 객체가 프로토타입의 역할을 하고, 이후 생성되는 shallow와 deep이 프로토타입 fit을 복사해서 사용하는 새로운 객체들이다.
- string과 StringBuilder의 차이를 알고 싶다면 다음을 참고하자.
[C#] 문자열 String, StringBuilder 차이점(feat 얕은 복사, 깊은 복사)
✍️먼저 아래의 간단한 C# 코드의 출력을 예상해보자. string s1 = "AA"; string s2 = s1; string s3 = string.Copy(s1); Console.WriteLine(s1); Console.WriteLine(s2); Console.WriteLine(s3); Console.WriteLine("--------------------------------
steadycodist.tistory.com
using System;
using System.Net;
using System.Text;
namespace StudyCSharp
{
public interface IExercise
{
// cf) 복사의 종류
// 1. 얕은 복사(Shallow Copy) : 주소 값이 같은 인스턴스 생성(한 쪽 수정시 다른 쪽이 영향을 받음)
// 2. 깊은 복사(Deep Copy) : 주소 값이 다른 인스턴스 생성(원본과 별개)
// 얕은 복사
IExercise ShallowCopyClone();
// 깊은 복사
IExercise DeepCopyClone();
}
public class ExerciseID
{
public int ID;
public ExerciseID(int Id)
{
this.ID = Id;
}
}
public class Fitness : IExercise
{
public string risk { get; set; } // 위험도(A~F)
public StringBuilder time { get; set; } // 평균 운동 시간(0h~10h)
public int strength { get; set; } // 강도(0~5)
public ExerciseID exerciseID { get; set; } // 넘버링(0~100)
public IExercise ShallowCopyClone()
{
// 얕은 복사(Shallow Copy)
// MemberwiseClone() 함수 : C# 내장함수, 얕은 복사로 객체의 단순 복사본을 생성하고 리턴해줌.
return (IExercise)MemberwiseClone(); // IExercise 타입으로 this의 복사본을 생성
// ** 주의 **
// string은 참조타입이지만 불변성을 가지므로 새로운 객체를 생성하게 되어 얕은 복사가 일어나지 않음.
// int 또한 불변성을 가지기 때문에 새로운 객체를 생성해서 재할당하는 과정이 일어나기 때문에 얕은 복사가 일어나지 않음.
// StringBuilder와 ExerciseID 클래스는 각각 string과 int를 얕은 복사로 어떻게 이용하는지 보여준다.
}
public IExercise DeepCopyClone()
{
Fitness clone = new Fitness(); // 새로운 객체 생성
clone.risk = risk;
clone.time = new StringBuilder().Append(time);
clone.strength = strength;
clone.exerciseID = new ExerciseID(exerciseID.ID);
return clone;
}
}
public class Crossfit : IExercise
{
public string risk { get; set; } // 위험도(A~F)
public StringBuilder time { get; set; } // 평균 운동 시간(0h~10h)
public int strength { get; set; } // 강도(0~5)
public ExerciseID exerciseID { get; set; } // 넘버링(0~100)
public IExercise ShallowCopyClone()
{
return this.MemberwiseClone() as IExercise;
}
public IExercise DeepCopyClone()
{
// 깊은 복사(Deep Copy)
Crossfit clone = new Crossfit(); // 새로운 객체 생성
// 현재 값 복사 -> 새로운 객체에 저장됨.
clone.risk = risk; /*clone.risk = string.Copy(risk);*/ // 둘 다 똑같이 깊은 복사가 일어남 -> string 불변성
clone.time = new StringBuilder().Append(time);
clone.strength = strength;
clone.exerciseID = new ExerciseID(exerciseID.ID);
return clone;
}
}
class Program
{
static void Main(string[] args)
{
// 최초 생성(Prototype)
Fitness fit = new Fitness();
fit.risk = "C";
fit.time = new StringBuilder("1.5h");
fit.strength = 4;
fit.exerciseID = new ExerciseID(1);
// 복사본 생성
Fitness shallow = (Fitness)fit.ShallowCopyClone();
Fitness deep = (Fitness)fit.DeepCopyClone();
Console.WriteLine("[원본]");
Console.WriteLine("위험도 \t\t: {0}", fit.risk);
Console.WriteLine("평균 운동 시간 \t: {0}", fit.time);
Console.WriteLine("강도 \t\t: {0}", fit.strength);
Console.WriteLine("운동 고유 번호 \t: {0}", fit.exerciseID.ID);
Console.WriteLine();
Console.WriteLine("[얕은 복사]");
Console.WriteLine("위험도 \t\t: {0}", shallow.risk);
Console.WriteLine("평균 운동 시간 \t: {0}", shallow.time);
Console.WriteLine("강도 \t\t: {0}", shallow.strength);
Console.WriteLine("운동 고유 번호 \t: {0}", shallow.exerciseID.ID);
Console.WriteLine();
Console.WriteLine("[깊은 복사]");
Console.WriteLine("위험도 \t\t: {0}", deep.risk);
Console.WriteLine("평균 운동 시간 \t: {0}", deep.time);
Console.WriteLine("강도 \t\t: {0}", deep.strength);
Console.WriteLine("운동 고유 번호 \t: {0}", deep.exerciseID.ID);
Console.WriteLine();
Console.WriteLine("-----------------------------------------------");
// 원본 값 수정
fit.risk = "Z";
fit.time.Replace("1.5h", "2h");
fit.strength = 3;
fit.exerciseID.ID = 99;
Console.WriteLine("-----------------------------------------------");
Console.WriteLine();
Console.WriteLine("[수정 후 원본]");
Console.WriteLine("위험도 \t\t: {0}", fit.risk);
Console.WriteLine("평균 운동 시간 \t: {0}", fit.time);
Console.WriteLine("강도 \t\t: {0}", fit.strength);
Console.WriteLine("운동 고유 번호 \t: {0}", fit.exerciseID.ID);
Console.WriteLine();
Console.WriteLine("[수정 후 얕은 복사]");
Console.WriteLine("위험도 \t\t: {0}", shallow.risk);
Console.WriteLine("평균 운동 시간 \t: {0}", shallow.time);
Console.WriteLine("강도 \t\t: {0}", shallow.strength);
Console.WriteLine("운동 고유 번호 \t: {0}", shallow.exerciseID.ID);
Console.WriteLine();
Console.WriteLine("[수정 후 깊은 복사]");
Console.WriteLine("위험도 \t\t: {0}", deep.risk);
Console.WriteLine("평균 운동 시간 \t: {0}", deep.time);
Console.WriteLine("강도 \t\t: {0}", deep.strength);
Console.WriteLine("운동 고유 번호 \t: {0}", deep.exerciseID.ID);
Console.WriteLine();
}
}
}
<참고 사이트>
Chapter 7. 원형 패턴(Prototype Pattern)
인프런에 있는 이재환님의 강의 게임 디자인 패턴 with Unity 를 듣고 정리한 필기입니다. 😀
ansohxxn.github.io
C# - 디자인 패턴 - 프로토 타입 패턴 ( Prototype Pattern)
1. 요약 GoF 중 생성 패턴으로 프로토 타입 패턴은 Clone을 이용하여 객체를 생성하는 방법입니다. 추상 팩토리 패턴의 경우 객체를 생성하는 코드를 파생 클래스에서 작성을 하였다면, 프로토 타
math-development-geometry.tistory.com
유니티 프로그래밍 패턴 (4) Prototype
Prototype Pattern 이란? 프로토타입 패턴Prototype Pattern은 생성하는 방법에 대한 패턴입니다. 생성할 객체들의 타입이 프로토타입인 인스턴스로부터 결정되도록 하며 인스턴스는 새 객체를 만들기 위
dev-mark.tistory.com
유니티(C#)로 사용해 보는 디자인 패턴_ProtoType Pattern_프로토타입
프로토 타입 이번 예제에서는 몬스터의 리스폰을 프로토 타입으로 구현해 보았습니다. Monster.cs public class KMS_Monster { public int health; public int speed; public int positionX; public int positionY; public virtual KMS_Mo
mrhook.tistory.com
C#으로 작성된 프로토타입 / 디자인 패턴들
/ 디자인 패턴들 / 프로토타입 / C# C#으로 작성된 프로토타입 프로토타입은 객체들(복잡한 객체 포함)을 그의 특정 클래스들에 결합하지 않고 복제할 수 있도록 하는 생성 디자인 패턴입니다
refactoring.guru
프로토타입 패턴 [Prototype Pattern] : 복사하여 인스턴스 만들기
이번에 다룰 패턴은 Prototype 패턴이다. 이 패턴은 인스턴스를 생성할 때 사용하는 패턴 중 하나인데, 객체를 복사하는 방식으로 인스턴스를 생성해 낸다. 마치 만화 나루토에서 나오는 그림자 분
orcacode.tistory.com
[객체 생성 패턴] Chapter 5-3. Prototype Pattern : 장단점
✍️ 프로토타입, 정리 프로토타입 패턴을 간단하게 정리하자면, 기존의 인스턴스를 청사진 삼아 새로운 인스턴스를 생성하는 방법으로 Prototype interface는 clone 메서드를 추상화하고, 클래스는
kangworld.tistory.com
[Design Pattern] 프로토타입 패턴(prototype pattern)
목차프로토타입 패턴이란?복사 연산 이용하기직렬화팩토리 패턴과의 결합정리하며참고자료 1. 프로토타입 패턴이란?객체를 생성할 때 종종 다른 객체의 값을 복사하여 사용할 때가 있다. 특히,
haedallog.tistory.com
[Dev] 프로토타입 패턴 (prototype)에 대해 알아보자
프로토타입 패턴 (Prototype Pattern) 프로토타입 패턴은 객체 지향 디자인 패턴 중 하나이며, 객체의 생성 과정을 단순화하여 새로운 객체를 생성하는 방법을 제공합니다. 이 패턴은 이미 존재하는
gr-st-dev.tistory.com