Deff_Dev

[디자인 패턴] 경량 패턴 (Flyweight Pattern) 본문

CS/디자인 패턴

[디자인 패턴] 경량 패턴 (Flyweight Pattern)

Deff_a 2024. 11. 7. 00:24

⚒️ 경량 패턴이 뭘까 ?

https://refactoring.guru/ko/design-patterns/flyweight

 

여러 객체 간에 공통된 상태(intrinsic state)를 공유함으로써 메모리 사용량을 줄이는 패턴

→ 동일한 정보를 가진 객체의 개수가 많을 때 사용

 

 

사용 방법

⇒  객체를 하나 생성하고, 해당 객체를 재사용하여 동일한 다른 객체들을 생성

 

이때, 하나의 객체의 정보를 가지고 여러 객체들이 공유하기 때문에 const/readonly 로 선언하여 변하지 않게 해야 하는 것이 좋음

 

[나무 랜덤 생성 예제 코드]

더보기
using UnityEngine;
using System.Collections.Generic;

// 나무의 내부 상태를 나타내는 클래스 (공유됨)
public class TreeType
{
    public Mesh mesh;
    public Material material;

    public TreeType(Mesh mesh, Material material)
    {
        this.mesh = mesh;
        this.material = material;
    }
}

// 개별 나무 인스턴스를 나타내는 클래스 (외부 상태)
public class Tree
{
    private TreeType treeType;
    private Vector3 position;
    private float rotation;
    private Vector3 scale;

    public Tree(TreeType treeType, Vector3 position, float rotation, Vector3 scale)
    {
        this.treeType = treeType;
        this.position = position;
        this.rotation = rotation;
        this.scale = scale;
    }

    public void Draw()
    {
        Matrix4x4 matrix = Matrix4x4.TRS(position, Quaternion.Euler(0, rotation, 0), scale);
        Graphics.DrawMesh(treeType.mesh, matrix, treeType.material, 0);
    }
}

// TreeType 객체를 관리하는 팩토리 클래스
public class TreeFactory
{
    private Dictionary<string, TreeType> treeTypes = new Dictionary<string, TreeType>();

    public TreeType GetTreeType(string name, Mesh mesh, Material material)
    {
        if (!treeTypes.ContainsKey(name))
        {
            treeTypes[name] = new TreeType(mesh, material);
        }
        return treeTypes[name];
    }
}

// 나무를 관리하고 그리는 매니저 클래스
public class ForestManager : MonoBehaviour
{
    public Mesh treeMesh;
    public Material treeMaterial;
    private List<Tree> trees = new List<Tree>();
    private TreeFactory treeFactory;

    void Start()
    {
        treeFactory = new TreeFactory();
        PlantTrees(1000);
    }

    void PlantTrees(int count)
    {
        TreeType treeType = treeFactory.GetTreeType("normalTree", treeMesh, treeMaterial);
        
        for (int i = 0; i < count; i++)
        {
            Vector3 position = new Vector3(Random.Range(-100f, 100f), 0, Random.Range(-100f, 100f));
            float rotation = Random.Range(0f, 360f);
            Vector3 scale = Vector3.one * Random.Range(0.8f, 1.2f);
            
            trees.Add(new Tree(treeType, position, rotation, scale));
        }
    }

    void Update()
    {
        foreach (Tree tree in trees)
        {
            tree.Draw();
        }
    }
}