C# Language
플라이급 디자인 패턴 구현
수색…
RPG 게임에서지도 구현하기
플라이급은 구조적 디자인 패턴 중 하나입니다. 유사한 객체로 가능한 한 많은 데이터를 공유하여 사용 된 메모리 양을 줄이는 데 사용됩니다. 이 문서는 Flyweight DP를 올바르게 사용하는 방법을 알려줍니다.
간단한 예를 들어 당신에게 그 아이디어를 설명해 드리겠습니다. RPG 게임을하고 있으며 캐릭터가 포함 된 거대한 파일을로드해야한다고 가정 해보십시오. 예 :
-
#
잔디입니다. 당신은 그것을 걸을 수 있습니다. -
$
가 출발점입니다. -
@
는 바위 다. 당신은 그 위에 걸을 수 없습니다. -
%
는 보물 상자입니다.
지도 샘플 :
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@############@@@@@######@#$@@@
@#############@@@######@###@@@
@#######%######@###########@@@
@############################@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
이러한 객체는 비슷한 특성을 가지므로 각지도 필드에 대해 별도의 객체를 만들 필요가 없습니다. 플라이급 사용 방법을 알려 드리겠습니다.
필드가 구현할 인터페이스를 정의합시다.
public interface IField
{
string Name { get; }
char Mark { get; }
bool CanWalk { get; }
FieldType Type { get; }
}
이제 필드를 나타내는 클래스를 만들 수 있습니다. 우리는 어떻게 든 그들을 식별해야합니다 (저는 열거 형을 사용했습니다) :
public enum FieldType
{
GRASS,
ROCK,
START,
CHEST
}
public class Grass : IField
{
public string Name { get { return "Grass"; } }
public char Mark { get { return '#'; } }
public bool CanWalk { get { return true; } }
public FieldType Type { get { return FieldType.GRASS; } }
}
public class StartingPoint : IField
{
public string Name { get { return "Starting Point"; } }
public char Mark { get { return '$'; } }
public bool CanWalk { get { return true; } }
public FieldType Type { get { return FieldType.START; } }
}
public class Rock : IField
{
public string Name { get { return "Rock"; } }
public char Mark { get { return '@'; } }
public bool CanWalk { get { return false; } }
public FieldType Type { get { return FieldType.ROCK; } }
}
public class TreasureChest : IField
{
public string Name { get { return "Treasure Chest"; } }
public char Mark { get { return '%'; } }
public bool CanWalk { get { return true; } } // you can approach it
public FieldType Type { get { return FieldType.CHEST; } }
}
앞서 말한 것처럼 각 필드에 대해 별도의 인스턴스를 만들 필요가 없습니다. 필드의 저장소 를 만들어야합니다. 플라이급 DP의 본질은 우리가 필요로 할 때만 동적으로 객체를 생성하고 아직 우리의 저장소에 존재하지 않거나 이미 존재한다면 그것을 반환한다는 것입니다. 이것을 처리 할 간단한 클래스를 작성합시다.
public class FieldRepository
{
private List<IField> lstFields = new List<IField>();
private IField AddField(FieldType type)
{
IField f;
switch(type)
{
case FieldType.GRASS: f = new Grass(); break;
case FieldType.ROCK: f = new Rock(); break;
case FieldType.START: f = new StartingPoint(); break;
case FieldType.CHEST:
default: f = new TreasureChest(); break;
}
lstFields.Add(f); //add it to repository
Console.WriteLine("Created new instance of {0}", f.Name);
return f;
}
public IField GetField(FieldType type)
{
IField f = lstFields.Find(x => x.Type == type);
if (f != null) return f;
else return AddField(type);
}
}
큰! 이제 코드를 테스트 할 수 있습니다.
public class Program
{
public static void Main(string[] args)
{
FieldRepository f = new FieldRepository();
IField grass = f.GetField(FieldType.GRASS);
grass = f.GetField(FieldType.ROCK);
grass = f.GetField(FieldType.GRASS);
}
}
콘솔의 결과는 다음과 같아야합니다.
Grass의 새로운 인스턴스 생성
Rock의 새 인스턴스 생성
그러나 우리가 두 번 그것을 원한다면 잔디는 한 번만 나타나는 이유는 무엇입니까? 처음으로 우리가 GetField
잔디 인스턴스를 우리의 저장소에 존재하지 않는다고 부르기 때문에 그것이 생성되었지만, 다음에 우리가 이미 풀을 필요로하므로 우리는 단지 그것을 반환합니다.