심화 디자인 패턴 (Advanced Design Patterns)
유니티 엔진에 내장된 기본 패턴 외에도, 복잡한 게임 시스템을 구축하고 유지보수하기 위해 개발자가 직접 구현해야 하는 강력한 디자인 패턴들이 있습니다. 이러한 패턴들은 코드의 가독성을 높이고 시스템 간의 결합도를 낮추는 데 큰 도움을 줍니다.
1. 팩토리 패턴 (Factory Pattern)
객체 생성 로직을 직접 노출하지 않고 인터페이스나 추상 클래스를 통해 객체를 생성하는 패턴입니다.
- 핵심 개념: 객체 생성 과정을 캡슐화하여, 생성되는 구체적인 클래스에 대해 클라이언트가 알 필요가 없게 만듭니다.
- 유니티 활용: 단순히 프리팹을
Instantiate하는 것을 넘어, 생성 시점에 특정 초기화 로직(Initialize)을 실행해야 하는 다양한 아이템이나 적 캐릭터 생성에 유용합니다.
2. 오브젝트 풀 패턴 (Object Pool Pattern)
객체를 매번 생성하고 파괴하는 대신, 미리 생성해둔 객체들을 재사용하는 성능 최적화 패턴입니다.
- 핵심 개념: 비활성화된 객체들의 컬렉션을 유지하며 필요할 때 꺼내 쓰고, 사용이 끝나면 풀로 반환합니다.
- 장점: 대량의 객체(예: 총알, 파티클) 생성 시 발생하는 가비지 컬렉션(GC) 스파이크와 프레임 드랍을 방지합니다.
- 참고: 유니티 2021 버전 이상부터는
UnityEngine.PoolAPI를 통해 내장 기능을 제공합니다.
3. 싱글톤 패턴 (Singleton Pattern)
클래스의 인스턴스가 오직 하나만 존재하도록 보장하고, 어디서든 전역적으로 접근할 수 있게 합니다.
- 핵심 개념:
Instance라는 정적 필드를 통해 유일한 객체에 접근하며, 중복 생성 시 기존 객체 외에는 파괴합니다. - 주의 사항: 전역 상태를 만들어 결합도를 높일 수 있어 "안티 패턴"으로 불리기도 하므로, 게임 매니저나 오디오 매니저처럼 반드시 하나만 필요한 경우에만 신중히 사용해야 합니다.
4. 커맨드 패턴 (Command Pattern)
실행될 기능을 객체로 캡슐화하여, 요청을 큐에 저장하거나 나중에 실행하고 실행 취소(Undo)할 수 있게 합니다.
- 핵심 개념: 메서드를 직접 호출하는 대신
Execute()와Undo()를 가진 커맨드 객체를 생성하여 실행합니다. - 활용 예시: 전략 게임의 턴 시스템, 격투 게임의 콤보 입력 시스템, 그리고 가장 대표적인 실행 취소/다시 실행(Undo/Redo) 기능 구현에 쓰입니다.
5. 상태 패턴 (State Pattern)
객체의 내부 상태가 바뀜에 따라 객체의 행동을 변경할 수 있게 해주는 패턴입니다.
- 핵심 개념: 각 상태를 별도의 클래스로 캡슐화하고, 상태 머신(State Machine)이 현재 상태의 로직을 실행하도록 관리합니다.
- 유니티 활용: 복잡한 캐릭터 컨트롤러나 적 AI를 구현할 때
switch나if문이 비대해지는 것을 방지하며, 유니티의 애니메이터(Animator) 시스템과 유사한 구조를 가집니다.
6. 옵저버 패턴 (Observer Pattern)
어떤 객체의 상태가 변하면 그 객체에 의존하는 다른 객체들에게 연락이 가고 자동으로 내용이 갱신되는 방식입니다.
- 핵심 개념: 발행자(Subject)와 구독자(Observer) 관계를 형성하여 느슨한 결합을 유지합니다.
- 유니티 활용: C#의
event나 유니티의UnityEvent를 사용하여 구현하며, 플레이어의 사망 알림, UI 업데이트, 업적 시스템 등에 널리 쓰입니다.
7. MVP/MVC 패턴 (Model-View-Presenter)
데이터(Model), 화면 표시(View), 로직(Presenter/Controller)을 분리하여 관리하는 아키텍처 패턴입니다.
- 핵심 개념: 데이터와 UI 사이의 의존성을 끊어 코드의 가독성과 테스트 용이성을 높입니다.
- 유니티 최적화: 유니티에서는 보통 View가 직접 Model을 관찰하지 않고 Presenter가 중간에서 중재하는 MVP 방식이 선호됩니다.
마무리: 디자인 패턴은 만능 해결책이 아니라 상황에 맞는 도구일 뿐입니다. 프로젝트의 규모와 복잡도를 고려하여 "단순함(KISS 원칙)"을 잃지 않으면서 적재적소에 적용하는 지혜가 필요합니다.
