[TIL] 디자인 패턴

muchan
muchan
∙∙조회 11

디자인 패턴, SOLID, KISS, DRY

디자인 패턴이란?

소프트웨어 개발에서 반복적으로 나타나는 문제에 대한 일반적 해결책

SOLID 원칙

  • S(단일 책임 원칙): 클래스는 한 가지 책임만 가진다. 한 클래스가 많은 일을 하지 않는다.
  • O(개방-폐쇄 원칙): 확장에는 열려 있고, 수정에는 닫혀있어야한다. = 기능을 추가할 때 기존 코드를 고치지 않고 코드 수정만 할 수 있다.
  • L(리스코프 치환 원칙): 서브 클래스는 기본 클래스가 쓰이는 자리에서 문제없이 대체될 수 있어야한다. (인터페이스로 분리해서 기능 쪼개자)
  • I(인터페이스 분리 원칙): 거대한 인터페이스 하나보다 작고 집중된 인터페이스 여러개가 좋다
  • D(종속성 역전 원칙): 상위 모듈이 하위 모듈을 직접 가져오면 안된다. (양쪽 모두 추상화에 의존해야함)

KISS 원칙

KISS = Keep It Simple, Stupid
복잡도는 필요할 때만 높이라는 원칙

  • 패턴은 필요할 때만 사용
  • 패턴이 맞는지 확신이 안서면 자연스럽게 기다려보자
  • 빠르고 쉬운 것이 곧 단순한 결과로 이어지진 않는다

DRY 원칙

DRY = Don't Repeat Yourself
반복하지 마라

  • 같은 로직이 여러 곳에 중복되면, 한곳만 고쳐도 다른 곳이 깨질 위험이 있다
  • 중복을 하나로 모으면 유지보수가 쉬워진다
  • KISS 와 마찬가지로 과한 추상화는 오히려 복잡도를 키운다

10개 패턴의 흐름:

그룹패턴무엇을 해결하나
생성팩토리 → 오브젝트 풀 → 싱글톤객체를 어떻게 만들고/재사용하고/공유할까
행동커맨드 → 상태 → 옵저버객체의 행동·상태·소통을 어떻게 구조화할까
아키텍처MVPUI와 데이터를 어떻게 분리할까
최적화·기타전략 → 플라이웨이트 → 더티 플래그알고리즘 교체, 메모리 절약, 불필요한 연산 줄이기

팩토리 패턴

게임 중 적, 아이템, 발사체, 장애물 등 다양한 생성 로직이 필요한 것들을 if/switch로 직접 관리하면 종류가 늘 때마다 분기가 늘어나고 코드가 비대해진다. 팩토리 패턴은 "공장"이라는 특수 객체에 제품 생성의 세부 사항을 맡긴다.

핵심 개념

  • 제품(Product): 공장이 만드는 대상. 인터페이스 IProduct를 따른다
  • 공장(Factory): 제품을 생성. 공통 기능이 필요하면 추상 클래스로 둔다
  • 구체 공장(ConcreteFactory): 특정 제품을 실제로 만드는 공장. 공장을 서브 클래싱해 여러 개 생성

실전 활용 사례

  • 적, 장애물 등 다양한 게임 플레이 요소의 런타임 생성
  • 다이얼로그 상자의 UI 요소 구성 같은 더 큰 작업의 일부

팩토리 패턴 = 객체 생성을 공장에 캡슐화해 분기 코드 축소

오브젝트 풀 패턴

쓰는 이유

  • 총알, 파티클, 적 처럼 짧은 수명의 객체를 대량 생성, 파괴하면 CPU 부담이 발생한다
  • 메모리 할당/해제가 잦으면 순간적으로 끊기는 가비지 컬렉션 스파이크가 발생한다

오브젝트 풀은 객체를 미리 만들어 두고 재사용 한다. 필요하면 풀에서 꺼내 활성화하고 다 쓰면 파괴 대신 비활성화하여 풀로 반환한다

핵심 개념

  • ObjectPool: 재사용할 객체들의 컬렉션을 보관한다
  • PooledObject: 풀링되는 각 객체에 붙는 작은 컴포넌트. 자신이 속한 풀을 참조해 반환을 돕는다
  • 흐름: 미리 채우기 -> 꺼내 쓰기 -> 돌려주기
  • 재사용 전에 Rigidbody나 NavMesh Agent 같은 것들 초기화하는 것이 중요하다

실전 활용 사례

  • 탄막 슈팅의 총알, 발사체
  • 폭발, 타격, 파티클, 데미지 텍스트
  • 적 스폰

싱글톤 패턴

  • 전체 씬에서 행동을 조정하는 객체가 정확히 하나만 필요할때(다양한 Manager 스크립트들)
  • 싱글톤은 불필요한 전역 상태 및 종속성을 유발할 수 있으니 조심해서 사용해야한다

핵심 개념

  • 클래스가 자신의 인스턴스 하나만 만들도록 보장
  • 하나의 인스턴스에 손쉬운 글로벌 액세스 제공

실전 활용 사례

  • 게임 플로우 관리자, 오디오 관리자, 저장 관리자
  • 오브젝트 풀 패턴을 싱글톤으로 만들면 풀링된 객체를 어디서든 쉽게 가져올 수 있다

커맨드 패턴

  • 실행 취소/다시 실행, 입력 내역 기록, 턴제 게임의 사전 계획 등은 일련의 행동을 추적해야 함
  • 메서드를 직접 호출하면 그 호출을 나중에 되돌리거나 재생하기 어려움
  • 하나 이상의 메서드 호출을 "커맨드 객체"로 캡슐화 -> 컬렉션에 담아 실행 타이밍을 제어

핵심 개념

  • 커맨드 객체(ICommand): 수행할 작업(Execute)과 되돌리는 방법(Undo)을 담음
  • 커맨드 호출자(CommandInvoker): 커맨드를 실행하고, 실행취소 스택으로 추적
  • 호출자는 커맨드의 내부를 모름 -> Execute/Undo만 호출
  • Execute/Undo가 서로 정확히 짝을 이룬다(커맨드 패턴의 핵심!!!!)

실전 활용 사례

  • 실행취소/다시실행: 스택 하나만 더 두면 다시실행 추가. 커맨드 취소 시 redo 스택으로 push, 새 이동 시 redo 스택 비우기
  • 콤보/연계기: 격투 게임에서 버튼 순서로 콤보를 트리거. 커맨드로 행동을 저장하면 콤보 설정이 간편
  • 리플레이: 커맨드 버퍼를 순서대로/역순으로 재생