내일배움캠프 35일차 TIL : UI 관련 구조 정리

김정환·2024년 11월 1일
0

키워드

  • UI 관련 구조 정리

실습 문제를 풀면서 정리하다가 좀 더 보강할 필요가 있을 것 같아서
정리해보았다.

UI 스크립트 관련

예전에 객체지향을 제대로 모를 때 UIManager를 만들고 필요한 기능을 모두 몰아서 작성한 적이 있다.
만약 기능별로 나눠지더라도 Page+기능이름 이렇게 클래스를 나눴는데
막상 페이지 안에는 팝업 창, 각종 슬라이더나 버튼들이 어질러져 있었다.

최근 UI 관련한 구조를 어떻게 잡으면 되는지 방향성을 얻었다.

몇 주전에 잡담방에 엄예찬 튜터님께서 올려주신 조언이다.
해당하는 전례가 많아서 매우 크게 찔렸다. 저격당했다
그래서 옛날에 했던 프로젝트를 열어서 다시 한번 보는데...

엄청난 길이를 자랑한다. 가관
내부는 더 가관이라서 열어보지 않았다.

SRP 위배

위에 아주 정직한 SRP를 위배하는 사례다.
클래스는 오직 단 하나의 책임(기능)을 담고 있어야한다.

그런데 위의 스크립트는 헤더에서만 봐도 알 수 있듯
로딩 + 첫 접속 여부 확인 + 카드 덱 표시 + 덱 수정 + 카드 수정 등등의 많은 기능이 포함되어 있다.

옛날에는 한 스크립트에만 접근하면 편하겠지라고 생각하면서 작업했겠지만
지금와서보면 미친듯한 비효율과 나락 간 유지보수성을 몸소 보여주는 행동이었다.

SRP를 지키는 이유

단일 책임의 원칙을 지키는 이유 중 하나는 1. 유지보수성을 높이기 위해서이다.

클래스가 하나의 책임만 갖고 있다면 이 책임에 관련된 변경 사항에서만 수정이 일어날 것이다.
그리고 SRP를 잘 지키고 있다면 어떤 클래스를 수정했을 때 대체로 다른 클래스의 수정이 동반되는 연쇄 작용이 없을 것이다.

그런 의미에서 위의 스크립트를 본다면 어디 한 곳을 건드리면
다른 곳이 터져나가는 폭탄같은 코드라고 할 수 있다.


단일 책임의 원칙을 지키는 또 다른 이유는 2. 코드의 가독성을 위함이다.

1000줄이 넘어가는 기능으로 꽉 찬 스파게티 스크립트 vs 많아봐야 100줄 언저리의 스크립트 5개

둘 중 어떤 것이 읽기 편할까 생각해본다.

지금 생각해보면 답은 당연히 후자이다.
전자는 소위 스파게티 코드라고하는 안 좋은 코딩 습관의 전형적인 예가 될 수 있다.

사람의 인지력은 한계가 있다보니 한 번에 너무 많은 정보는 처리할 수 없다.
코드를 작성한 당시에는 모든 것이 이해가 되겠지만 3개월 뒤의 자신이 다시 이 코드를 본다면
이해하는데 개발한 시간만큼 걸릴 수 있다.
(이건 UML을 작성할 수도 없다.)

그런 측면에서 후자의 코드는 파악하는데 큰 어려움이 없을 것이다.
한 번에 읽으면 되는 코드량이 100줄 미만일 것이고 그 내용들도 클래스가 가진 책임에 관련된 것이다.
구조를 파악하고 이해하는 것이 상대적으로 간단해진다는 의미이다.
(여기에 UML같이 다이어그램이 있다면 더 쉬워질 것이다.)

그리고 이런 좋은 가독성은 다시 유지보수성을 높이는 효과로 이어진다.
구조에 대해 이해하는 시간이 적게 들고, 한 스크립트를 수정하더라도 그 영향이 다른 스크립트에 연쇄적으로 작용하진 않을 것이다.
(물론 이것도 케이스 바이 케이스이긴 하다.)

개선해보기

튜터님의 조언을 위의 예시에 적용해본다면

이렇게 매우 많은 책임을 진 클래스를 다음과 같이 분리하고
필요한 UI 오브젝트에 컴포넌트로 붙여서 관리하면 될 것이다.

이래두면 다음 번에 다시 찾아볼 때 기능에 따라 바로바로 스크립트와 관련된 UI를 찾을 수 있을 것이다.

정리

위에서는 SRP에 대해서만 이야기했지만, 저런 거대한 코드 덩어리는 OCP도 위배하고 있을 가능성이 높다.
기능이 추가되면 확장이 아니라 스파게티 코드를 따라가면서 수정하고 있을 가능성이 높다.

나머지(의존 역전, 리스코프 치환, 인터페이스 분리) 원칙들은 위 예시에서 적용이 불가능하다.
애초에 상속 자체를 이용하고 있지 않아서 언급할 수가 없다.

하나의 클래스에서 모든 것을 관리하면 편리하겠지라는
이상한 사상에서 시작된 작업은 결국에 프로젝트 관리에 매우 큰 비효율과 위험을 가져온다.

UI 작업을 할 때도 객체지향을 적용해서 하나의 기능에 맞는 스크립트를 작성해서 작동하도록 하는 것이 바람직하겠다.

추가

UI에 관련된 구조에 적용해볼 수 있는 개념이 있었다.

MVC(모델 - 뷰 - 컨트롤러) 패턴

이 패턴은 UI를 표현할 때, 크게 3가지의 역할군으로 클래스를 나누라는 패턴이다.

  1. 모델 (Model) : 데이터를 저장하는 역할이다.
    전적으로 값을 저장하는 데이터 컨테이너로 로직이나 계산을 수행하지 않는다.
  2. 뷰 (View) : UI를 의미한다.
    데이터의 그래픽 표현을 형식화하고 화면에 표현한다.
  3. 컨트롤러 (Controller) : 데이터의 연산 처리를 수행하는 역할이다.
    게임 데이터를 연산 및 변경을 처리한다.

종종 팀프로젝트를 하다보면 많이 받은 피드백 중 하나가
데이터의 정의와 UI 표현이 결합되어 있는 경우가 종종 보이니 이것을 나중에 고치는 것을 권장함 이었다.

지금 생각해보면 데이터의 정의와 이 표현을 하나의 클래스에서 같이 수행한 경우가 많았다.

예를 들면

  • 체력을 표현하는 클래스가 UI 제어도 같이하고 있는 경우
  • 퀘스트에 대한 정의가 퀘스트 UI 표기도 같이 수행하고 있는 경우

그리고 피드백을 통해서 개선하는 방향은 위의 MVC 패턴을 적용하는 방향이었던 것 같다.

유의

  • 이 방법은 UI를 표현할 때 사용하는 구조 패턴이다.
  • 간단한 UI 기능인 경우 오히려 복잡해질 수 있다.

#내일배움캠프 #스파르타내일배움캠프 #스파르타내일배움캠프TIL

profile
사파 개발자

0개의 댓글