Factory Pattern in Unity

최정훈·2024년 12월 23일
0

Factory Pattern의 필요성


버튼을 누르면 Cube, Sphere의 3D 오브젝트를 생성하는 코드를 작성한다고 하면, 아래와 같이 작성할 수 있다.

using System;
using UnityEngine;

public class NonFactoryPattern : MonoBehaviour
{
    public enum Shape
    {
        Sphere,
        Cube
    }
    
    [SerializeField] private GameObject Sphere;
    [SerializeField] private GameObject Cube;

    void CreateShape(Shape shape)
    {
        switch (shape)
        {
            case Shape.Sphere:
                Instantiate(Sphere, transform.position, Quaternion.identity);
                break;
            case Shape.Cube:
                Instantiate(Cube, transform.position, Quaternion.identity);
                break;
            
            // 도형이 추가될 때 마다, 코드가 길어짐
        }
    }

    public void CreateCube()
    {
        CreateShape(Shape.Cube);
    }

    public void CreateSphere()
    {
        CreateShape(Shape.Sphere);
    }
}

이는 의도한대로 문제없이 작동한다. 하지만, CreateShape 메서드는 도형의 종류가 추가될때마다 변경되어야하는 번거로움이 있고, 이는 소프트웨어 디자인원칙의 OCP(Open Close Protocol)을 위배한다.

위 코드가 도형이 아니라, 인 게임에서 각종 아이템을 생성해주는 ItemManager의 역할을 있다고 가정하면 탄약, 쉴드, 힐팩과 같은 다양한 아이템이 추가될 때마다 코드에 변경이 요구되고, 이는 상당히 번거로울 것이다. Factory Method 방식을 통해서 이를 해결할 수 있다.

Factory Method


Factory Method 방식은 클래스 객체의 생성을 서브 클래스에 맡기는 방식이다. 위의 상황을 Factory Method 방식으로 변경하기 위해서, Factory들의 상위 클래스인 BaseFactory, 도형들의 상위 클래스인 BaseShape 클래스를 추상클래스로 생성하고, 각 도형과 그 도형을 담당하는 Factory들이, 이를 상속받도록 변경했다.

//BaseFactory.cs
public abstract class BaseFactory : MonoBehaviour
{
    // Factory Method
    public abstract void CreateShape();
}

//BaseShape.cs
public abstract class BaseShape : MonoBehaviour
{
    public abstract void CreateShape();
}

그리고 이들을 상속받는 Concrete Factory인 Cube, Sphere Factory와 Concrete Product인 Cube와 Sphere를 생성한다.(예시로는 1개만 들었다.)
//Cube.cs
public class Cube : BaseShape
{
    public override void CreateShape()
    {
        Debug.Log("Cube created");
    }
}

//CubeFactory.cs
public class CubeFactory : BaseFactory
{
    [SerializeField] private BaseShape cubePrefab;
    
    public override void CreateShape()
    {
        cubePrefab.CreateShape();
        Instantiate(cubePrefab);
    }
}

이제 생성하고자 하는 Cube와 Sphere Prefab에 각각 Cube.cs, Sphere.cs를 추가하면 의도한 대로 작동하는 것을 확인할 수 있다.

이러한 Factory Method방식의 장점은, 다른 유형의 도형이 추가되더라도 기존의 코드를 수정하지 않고, 해당 도형을 담당하는 새로운 Concrete Factory를 만들면 되기때문에, OCP원칙을 준수하면서, Factory Method 방식을 사용하지 않았을 때보다, 유지보수가 용이해진다는 점이다. 하지만, 코드의 양이 길어진다는 단점 또한 존재한다.

profile
게임개발자(희망)의 공부일지

0개의 댓글