[디자인패턴] Flyweight Pattern 경량패턴
1. 간단한 요약
내용이 같은 객체가 이미 있으면 새로 객체를 또 만들지 않고 그 내용 같은 기존 객체를 공유한다.
2. 사용은 언제 ?
게임에는 많은 반복작업이 들어간다. 대표적인 예는 게임에서 나무나 돌과 같은 지형 지물의 구현이다.
맵 하나에 지형 지물을 일일히 전부 다르게 구현하는 게임은 사실상 존재하지 않는다. 대부분 여러개의 돌이나 나무 오브젝트 같은 경우를
미리 만들어놓고 여러개를 공유해서 사용한다.
이런경우 이미지를 메모리에 나무마다 띄워둘 필요 없이 하나의 메모리에 이미지를 올려두고 여러개의 나무는 단지 하나의 이미지를 참조만 하는 형식으로 사용하면 좋다.
위의 예제에서는 나무의 고유한 값(나무마다 이미지는 변할 필요가 없다.)
나무 마다 다른 값(나무가 하나의 좌표에 모여서 심어질 필요는 없다)
을 나누어서 표현했다.
그래픽에서 이 표현을 Instance Rendering 이라고 한다.
3. 예제
예시1)
using System.Collections.Generic;
using UnityEngine;
public class WeaponFlyweight
{
private GameObject prefab;
private string name;
private string description;
public WeaponFlyweight(GameObject prefab, string name, string description)
{
this.prefab = prefab;
this.name = name;
this.description = description;
}
public void Spawn(Vector3 position)
{
GameObject.Instantiate(prefab, position, Quaternion.identity);
}
public void Display()
{
Debug.Log(string.Format("Name: {0}, Description: {1}", name, description));
}
}
public class WeaponFactory
{
static Dictionary<string, WeaponFlyweight> dic = new Dictionary<string, WeaponFlyweight>();
public static WeaponFlyweight GetWeapon(string ID)
{
if (!dic.ContainsKey(ID))
{
// 새로운 공유 객체 생성
GameObject prefab = Resources.Load<GameObject>("Weapons/" + ID);
string name = "Weapon " + ID;
string description = "This is " + name;
WeaponFlyweight weapon = new WeaponFlyweight(prefab, name, description);
dic.Add(ID, weapon);
}
return dic[ID];
}
}
위의 코드는 팩토리 패턴과도 연관된 경량 패턴이다. 팩토리 패턴이 경량 패턴에 속하는 것은 아닌데(팩토리에서 새로운 객체를 만들어서 반환할 경우도 있기 때문) ,관련해서 쓰는 경우가 잦다.
위의 코드를 보면 동일한 메모리에 있는 객체를 참조해서 쓰고 있다. <= 경량 패턴
예시 2)
using System.Collections.Generic;
using UnityEngine;
public class ImageFlyweight
{
private string imageName;
private Texture2D image;
public ImageFlyweight(string imageName)
{
this.imageName = imageName;
this.image = Resources.Load<Texture2D>("Images/" + imageName);
}
public void Display(Vector3 position)
{
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.position = position;
cube.GetComponent<Renderer>().material.mainTexture = image;
}
}
public class ImageFactory
{
private static Dictionary<string, ImageFlyweight> imageDictionary = new Dictionary<string, ImageFlyweight>();
public static ImageFlyweight GetImage(string imageName)
{
if (!imageDictionary.ContainsKey(imageName))
{
ImageFlyweight imageFlyweight = new ImageFlyweight(imageName);
imageDictionary.Add(imageName, imageFlyweight);
}
return imageDictionary[imageName];
}
}
public class ExampleUsage : MonoBehaviour
{
void Start()
{
ImageFlyweight imageFlyweight1 = ImageFactory.GetImage("image1");
ImageFlyweight imageFlyweight2 = ImageFactory.GetImage("image1");
ImageFlyweight imageFlyweight3 = ImageFactory.GetImage("image3");
imageFlyweight1.Display(new Vector3(0, 0, 0));
imageFlyweight2.Display(new Vector3(1, 0, 0));
imageFlyweight3.Display(new Vector3(2, 0, 0));
}
}
위의 코드는 간단한 그래픽 예제이다. 맨위에 숲에 들어갈 나무들을 코드로 표현한 느낌이다.
위 코드는 동일한 그래픽 리소스를 참조하고, Vector값만 다르게 설정해서 위치좌표만 다르게 만들어줬다.
'게임공부 > 디자인패턴' 카테고리의 다른 글
[디자인 패턴] 객체 지향 디자인 패턴 1 (1) | 2023.05.15 |
---|---|
객체 지향 설계 5대 원칙 SOLID (1) | 2023.05.14 |
[디자인 패턴] 디자인 패턴 개요 (0) | 2023.05.12 |
Design Patterns - 싱글톤(Singleton) (0) | 2023.04.28 |