타입 객체 패턴

박지예·2026년 9월 7일

공부2026

목록 보기
18/20

종류(type)을 클래스가 아니라 객체로 표현하는 패턴이다.
원래 상속으로 표현하던 분류 체계를, 인스턴스가 타입 객체를 참조하는 형태로 바꾼다.

Unity 의 scriptable object가 타입 객체 패턴의 대표적인 예시다.

기존 enum 으로 관리하는 데이터들을 타입객체 패턴으로 전환할 수 있다.

public class CurrencyType
{
    public string Id { get; }
    public string IconName { get; }
    public string DisplayName { get; }

    private CurrencyType(string id, string iconName, string displayName) { ... }

    public static readonly CurrencyType Gold = new("gold", "icon_gold", "골드");
    public static readonly CurrencyType Gem  = new("gem",  "icon_gem",  "보석");
}

enum 과 비교해서 type 객체 패턴으로 currency를 관리하면 다음과 같은 장점이 있다.

1.데이터가 타입과 함께 산다.
enum 일때는 currencyType.Gold는 그냥 정수 0이였고, 아이콘, 표시명 등 부속 정보는 전부 바깥의 switch 문이나 dictionary에 흩어져 있다.

// 전
string GetIcon(CurrencyType t) => t switch {
    CurrencyType.Gold => "icon_gold",
    CurrencyType.Gem  => "icon_gem",
    ...
};

// 후
currency.IconName

2.동작도 붙일 수 있다
데이터뿐 아니라 메서드나 델리게이트를 필드로 가질 수 있다. Format(long amount) 같은걸 타입 객체가 직접 처리하면 호출부에서 분기가 사라진다.


그러나 타입객체 패턴을 적용하려면 감수해야하는 지점이 있었다.

1.switch 패턴 매칭이 안된다.
C#의 switch 문으로 사용하려면 if / else if 체인이나 switch {} 표현식의 when 절로 바꿔야 한다.

2.직렬화가 자동이 아니다.
enum은 인스팩터에서 드롭다운으로 뜨고 세이브에 정수로 들어가지만, 순수 클래스는 Unity 인스팩터에 노출되지 않고 JsonUtility 로도 안된다.
세이브에서는 id 문자열만 쓰고, 로드시 ID -> 인스턴스로 되돌리는 조회 경로가 필요하다.

private static readonly Dictionary<string, CurrencyType> _byId = ...;
public static CurrencyType FromId(string id) => _byId[id];

그래서 생각했던 방법이 id 자체는 enum으로 유지하는 거였다.
앞서 말했던 enum의 역할을 크게 2개라고 생각했는데,

  1. 식별자 - 이건 gold다.를 표현하고 저장하는 키.
  2. 분기 근거 - switch로 종류별 데이터와 동작을 흩뿌리는 축.

이 패턴의 전환 목적은 2번을 없애는거지 1번이 아니라고 판단했다.

public enum CurrencyId { Gold, Gem, Ticket }

public class CurrencyType
{
    public CurrencyId Id { get; }
    public string IconName { get; }
    public string DisplayName { get; }
    public bool IsHardCurrency { get; }
    // ...
}

Unity 에서는 직렬화와 인스팩터 비용을 계산하면 위 처럼 관리하는게 더 낫다는 생각을 하였다.
이미 운영중인 서비스 이기도 했고.

profile
게임 클라이언트 개발자

0개의 댓글