디자인 패턴 정리: 싱글톤 패턴, 오브젝틑 풀 패턴, 전략 패턴, 상태 패턴

ggm-_-·2025년 1월 30일
0

TIL (Tody I Learn)

목록 보기
52/53

2025.01.24(금)
TMI: 내일배움캠프 Unity 6기의 스탠다드반 특강에서 디자인 패턴 강의를 진행하였었다. 반이 달라 듣지 못하였었어도 '무조건 들어야겠다~' 싶을 정도로 중요한 내용이기에 시간나면 들어야지라는 생각은 했었는데, 시간이 촉?박하고 '이거 들으면 프로젝트 진행이 더뎌지지 않나?' 하는 생각에 자꾸 멀리하게 되었었는데 드디어 듣게 되었다.
아무튼 여차저차 저번주에 강의를 들으며 메모한 내용을 바탕으로 정리한다.
본격, 내가 보려고 정리한 디자인 패턴 Let's go~

Unity 6기 스탠다드 반에서 송지원 튜터님이 강의하신 디자인 패턴 강의를 바탕으로 작성한 글입니다.

이 글은 99.9%의 강의 내용과 0.1%의 사족으로 이루어져 있습니다. (이것도 사족인가?)

코딩이란 무엇인가?

코딩은 무공이다

  • 갑작스럽게 깨달음이 찾아오는가?
  • 갑자기 그 깨달음이 사라지기도 하는가?
  • 윗대가 남긴 구결이 있는가?

이 모든 조건을 만족하는 코딩은 무공! 갈고 닦아서 자신의 코딩 기술을 연마해서 무림고수가 되자!


디자인 패턴

디자인 패턴이란 무엇인가?

디자인 패턴은 기출문제집이다.

  • 천재 개발자들(GoF)이 OOP의 주요 설계 어려움들을 푸는 기출문제집을 제공
  • 이후 언어별로 디자인 패턴들이 증식

Gang of Four(GoF) : 네 명의 천재 개발자
네 명의 천재 개발자들이 소프트웨어에서 공통적으로 나타나는 주요 구조 및 설계들을 모아서 디자인 패턴이라고 하였다.

💡 디자인 패턴을 얼마나 아는지가 중요한 게 아니라, 디자인 패턴을 가지고 어떻게 해결하는지가 중요하다!

디자인 패턴을 쓰면 좋은 이유?

  • 복잡하고 난해한 문제를 패턴화해서 풀 수 있다.
  • 다른 개발자와 소통할 때 간단하게 설명할 수 있다.

디자인 패턴을 사용할 때 주의해야 할 점

디자인 패턴은 문제를 푸는 데 사용해야 한다!

  • 디자인 패턴을 쓰기 위해 문제를 만드는 경우를 조심할 것
  • 디자인 패턴을 무지성으로 활용하는 것은 매우 지양할 것

☝ 디자인 패턴을 사용할 때, 항상 이 패턴이 정말 필요한 지 점검해보고 써야하는 이유를 생각해보자!

포트폴리오에서는 이 디자인 패턴을 왜 썼는지를 어필하는 것이 매우 중요한 포인트이다!


이 글에서 다룰 패턴들

  • 싱글톤 패턴
  • 오브젝트 풀 패턴
  • 전략 패턴
  • 상태 패턴

싱글톤 패턴

접근이 잦은 핵심 기능에 대한 전역적 접근을 허용하는 패턴

왜 쓸까?

  • 중요하고 유일하게 존재하는 대상을 쉽게 접근하고 싶어서

구현

  • 유일하다 - 추가적으로 생기는 것을 제한하는 방법이 필요
  • 전역적으로 접근이 가능하다 - public static을 통해 구현

>static은 항상 메모리 상에 존재하게 된다.

싱글톤 확장 - Generic과 연계

왜 쓸까?

  • 싱글톤 객체들 간의 유사성이 매우 높음
  • 그런데 단순하게 상속으로 상위클래스로 단순하게 접근하긴 싫음
    (각 싱글톤의 고유 기능 캐스팅 없이 바로 쓰고 싶다는 것)

👉 Generic -> '일반화 프로그래밍' 이라고 생각한다

제네릭 싱글톤 작은 팁

  1. 라이플 사이클 주의 (Awake / Start)

  2. 모든 싱글톤을 DontDestoryOnLoad할 필요가 없다.
    -> 개인적으로 Singleton<T> / SingletonDontDestory<T> 로 네이밍 구분 추천
    -> DontDestory 했는데, 참조하는 객체들이 null되어 있는 것이 더 피곤할 수 있음

  3. Init 이라는 메서드를 만들어서 초기화 순서에 맞게 관리할 수 있다.

매니저 특징

  • 유일성이 있어야 한다.
  • 참조가 많이 발생한다.

오브젝트 풀 패턴

생성/파괴가 반복되는 오브젝트를 재활용하는 패턴

왜 쓸까?

  • 할당/해제에 걸리는 성능 낭비와 메모리 낭비를 줄이고 싶어서
    (if문을 줄이는 것보다, 메모리를 할당하고 해제하는 것이 더 많은 낭비를 야기한다)
  • 풀(Pool)은 뽑힐 수 있는 대상을 묶는 단위라고 생각하면 된다.

🔥 로딩할 때 0.1초 기다리는 것은 상관없지만, 6프레임 이상이 지나가는 게임 플레이 시간에서의 0.1초는 끊기면 안된다.
(60fps의 게임이라고 했을 때, 0.1초에 6개의 프레임이 지나간다.)

구현

필수 구현 사항

  • 파괴하는 대신 오브젝트를 비활성화한다.

선택 구현 사항

  • 필요한 만큼을 미리 생성해두고, 비활성화해둔다.
  • 생성 대신 비활성화된 오브젝트를 찾아 활성화한다.
  • 미리 생성해둔 양 이상을 요구한다면 추가로 생성한다.

🍳 포트폴리오에서 자주쓰는 오브젝트 풀 예시:
스크롤 뷰에서 스크롤을 내릴 때, 보여지는 만큼의 content 정도의 오브젝트를 만들어놓고 위, 아래로 내릴 때, 재활용해서 사용한다.

오브젝트 풀 고려사항

  • 씬 로드 시 오브젝트 풀의 모든 오브젝트를 전부 다 생성해 두어야 함
    -> 씬 로드 시간을 매우 길게 만들 수 있음
    -> 필요한만큼만 생성할 것

유니티에서 제공하는 오브젝트 풀

UnityEngine.Pool

  • 2021버전 이후부터 제공됨
  • 간단하게 델리게이트를 걸어 커스터마이징 가능

activeSelf: 자기가 active되어있는지
activeInHierarchy: Hierarchy 창에서 active되어있는지(부모 오브젝트가 꺼져있으면 Hierarchy에서 꺼짐)


전략 패턴

마치 골프에서 상황에 맞게 채를 바꾸는 것처럼, 상황에 맞게 로직군을 바꿔주는 방식의 패턴

왜 쓸까?

  • 원본 클래스를 건드리지 않고 다양하게 추가되는 방식을 대응하고 싶어서

전략이 뭐길래
전략이란? 로직들의 군(묶음)을 정의하고, 로직군들간에서 교체가능하게 해준다.
예를 들어, 일반적인 기능들을 포함하고 있는 로봇이 있다고 하자. 이 로봇이 상황에 따라 청소 소프트웨어를 구동하게 되면 청소 로봇으로, 경비 소프트웨어를 구동하게 되면 경비 로봇으로서 동작할 것이다.
이처럼, 같은 역할군이지만 전략에 따라 다른 기능을 대입해주는 것이 전략 패턴이라고 할 수 있다.

구현

  • 전략 패턴을 구현하기 위해서 전략 인터페이스를 정의한다.
  • 전략 인터페이스에서는 세부 동작을 구현
    (로봇 전체를 상속 받는 것이 아닌, 로봇의 행동 하나를 상속받는다고 생각)

전략패턴은 보통 Strategy를 컨벤션으로 붙여서 사용(ex: CleanStartegy)

전략 패턴의 활용 - UI 연출

연출에 대한 구현을 UIView클래스에서 직접 하지 않고, UI를 보여주거나 숨기는 방법을 각 전략 인터페이스에서 가능하도록 구현

  • 인터페이스로 전략패턴을 구현해서 UI를 보여주는 연출과, 숨기는 연출을 인터페이스로 실행하게 만든다.
    -> 그러면, 수정 없이 인터페이스를 상속받는 코드만 추가해서 보여주는 연출과 숨기는 연출을 추가할 수 있다.

상태 패턴

idle, angry, dead와 같이 여러 상태를 두고, 해당 상태일 때 그 상태에 맞는 행동을 하게 만드는 패턴

왜 쓸까?

  • 여러 상태들이 있고, 실행되는 로직이 달라짐을 체계적으로 관리하고 싶어서

대표적인 사용 사례: 애니메이터
👉 코드로 구현하는 방법도 있지만, 사실상 Animator가 대표적인 사례이다.

FSM

Finite State Machine의 약자, 유한 상태 기계

  • N개의 가능한 상태, 현재 상태, 상태 간의 전환으로 구성되어 있다.
    (애니메이터가 대표적인 FSM)

FSM 구현

숙련 주차의 적 구현처럼, N개의 상태를 두고, 그 안에서 상태의 전이가 일어나는 형태의 구현에서 활용

구성요소

  • 상태들을 전환하는 역할을 하는 StateMachine
  • 실행되어야 할 로직을 정의하는 State들로 구성

HFSM

Hierarchial Finite State Machine의 약자, 계층형 유한 상태 기계
-큰 개념의 상태와, 실제 행동을 결정하는 세부 상태를 구분하여 구현

  • 예시
    Idle / Jump / Walk / Run 이 아니라
    Idle / Move (Jump, Walk, Run)으로 나누는 것

디자인 패턴을 공부하며 느낀 점

디자인 패턴을 공부하고 정리하면서 느낀 점은 알아놓았을 때, 다양한 상황에 활용하여 적용하여 보다 객체지향적인 프로그래밍을 할 수 있겠다는 것이다.

주의사항에서도 말했듯이, 디자인 패턴에 매몰되어 패턴을 위한 코딩을 하지 않도록 주의해야 겠지만, 잘 활용한다면 유지보수와 확장성이 좋은 코드를 작성하여 일의 능률을 늘릴 수 있을 것이다.

여기까지의 패턴들의 개념에 대한 부분은 이제 이해하였는데, 이것을 직접 활용해보면서 패턴들을 언제든지 상황에 맞게 쓸 수 있는 나의 무기로 만들어야 겠다.

(전략 패턴처럼 패턴을 꺼내쓰는 나)


다음 글에서 다룰 패턴들

  • 옵저버 패턴
  • 이벤트 버스 패턴
  • 명령 패턴

다음글: 디자인 패턴 정리: 옵저버 패턴, 이벤트 버스 패턴, 명령 패턴

profile
미숙한 초보 게임 개발자

0개의 댓글

관련 채용 정보