효율적인 UI 구조를 위해 MVP 패턴을 사용해보았습니다
들어가며
안녕하세요 저는 특성화고 컴퓨터게임제작과를 다니며 현재는 특기자 전형을 위한 포트폴리오를 준비 중인 고3 민서라고 합니다. 저는 현재 포트폴리오에 저의 가치를 드러낼 수 있는 내용을 적기 위해 고민하고 개발해나가고 있는데요. 포트폴리오를 채워나가면서 구조 설계, 디자인 패턴과 관련된 얘기가 들어가면 좋겠다고 생각하여 오늘 소개할 주제를 선정하게 되었습니다.
MVP 패턴은 무엇일까
MVP 패턴은 Model, View, Presenter 세 가지 요소로 UI를 관리하는 디자인 패턴입니다. Model은 데이터를 가지고 있고, View는 사용자에게 보여지는 UI를 Presenter는 Model의 데이터와 View의 UI 기능을 관리하는 친구입니다. 제가 공부했던 블로그의 사진은 이렇게 소개하고 있네요
UI는 너무 활용도가 넓고 한 객체마다 어디까지 책임을 부여하고 분리해야 할지 판단하기 어려웠고 UI 구성을 조금이라도 바꾸면 이곳저곳에서 나오는 오류들 때문에 항상 게임 개발할 때마다 UI 작업을 제일 싫어했던 기억이 나네요. 그렇기에 지금이라도 공부해야 한다고 생각했습니다.
뭔가 구현했던 구조들을 다 설명하려고 했는데 그렇기에는 글이 너무 길어지고 TMI일 것 같아서 싹 다 지우고 어떤 형태로 구현했는지만 간단하게 그려보겠습니다.
이건 실제로 제가 테스트해보기 위해서 만들었던 팝업창 UI입니다. Bind 함수를 통해 팝업창에서 어떤 텍스트가 띄워질 것인지, 버튼에 표시되는 텍스트는 무엇인지, 버튼이 어떤 기능을 수행하는지를 넘겨주면 Presenter에서 정보를 받아 View로 표시해주는 거죠. Unity와 C#의 특징 덕분에 구현하다 보니 앞에 보여줬던 사진의 구조와는 다르게 View는 Presenter를 몰라도 되고 Presenter는 Model을 몰라도 되게 되었습니다. 결합도가 느슨해졌다는 것이니 오히려 좋아요
더 개선할 수 있지 않을까?
제가 짠 코드에서 View 기능을 담당하는 코드는 ViewBase라는 객체에서 모든 역할을 다 해주기 때문에 사실 View 코드는 매우 간단합니다.
View에서는 사실 보여지는 부분만 관리하기 때문에 각 View마다의 차이점은 UI가 어떻게 구성되어있는지 밖에 없습니다. 그렇기 때문에 저는 ViewBase 라는 부모 클래스를 만들어주고 UI의 공통적인 특성(ESC를 통해 닫을 수 있다, 중첩이 가능하다, 게임이 시작하자마자 보인다 등등)을 정의해놨기 때문에 View의 코드는 매우 간단해질 수 있었던 것이죠. 하지만 어차피 다른 프로젝트에서도 계속 재활용하며 사용할 코드라면 더 편리했으면 좋겠습니다.
CodeDOM을 사용해보자
CodeDOM은 C#에서 제공하는 기능 중 하나로 무려 런타임 중에 코드를 생성할 수 있게 해줍니다. 물론 그만큼 느리기 때문에 보통 인게임에서는 사용하지 않고 제 경우와 같은 에디터를 만들거나 개발 툴을 만들 때 사용합니다.
CodeDOM을 사용해서 우선 UI를 배치하고 그 UI를 인식하여 코드를 짜주는 친구를 만들면 좋지 않을까라는 아이디어로 시작해서 결국
성공했습니다! 처음 다뤄보는 기능이기도 하고 자료가 공식 문서밖에 없어서 중간에 오류가 많았지만 잘 작동하는 것을 보니 기분이 좋네요
마무리하며
제가 여러 현업 개발자들을 만나며 얻었던 조언 중 하나는 게임 개발자들을 각자 자신만의 ‘자산’을 보유하고 있다는 것이었습니다. 자산이 잘 쌓여있는 개발자는 코드 조금만 짜도 하나의 게임을 금방 완성할 수 있을 정도라고 하더라구요. 처음 맨땅에서 게임을 만드는 것은 무척이나 어려운 일이기 때문에 이번 주에 만든 MVP 패턴과 같이 미리 구조와 기능을 만들어두면 이 코드는 모든 프로젝트에서 쓸 수 있게 되고 그것이 저의 자산이 된다는 이야기였습니다. 이번 주는 그런 오래 두고두고 쓸 ‘자산’을 만들었다는 점에서 매우 의미가 깊었던 그리고 배울 것이 많았던 주였던 것 같습니다.
다음 주에 만들 것
다음 주는 포트폴리오에 최적화에 관한 이야기가 들어가면 좋을 것 같아서 이번에 새로 Unity에서 선보인 DOTS(Data Oriented Technical Stack) 와 기존 C#의 Garbage Collector의 단점을 보완하기 위해 만든 Object Pooling, 이 두 가지 최적화 기법을 비교하는 보고서를 작성해보려고 합니다. DOTS는 멀티스레드와 연관이 있는 내용이라 얼마나 어려울지, 오래 걸릴지는 감도 안 잡히지만 그래서 그런지 기대가 되기도 합니다.
사실 이런 글을 써보는 게 거의 처음이라, 다른 분들의 글을 보면서 어디까지 간결하게 쓰고, 어디까지 자세하게 써야 할지 모르겠어서 고민하며 지우고 쓰고를 반복하다 보니 꽤 오래 걸렸습니다. 최대한 간결하지만 자세하게(?) 쓰려고 하다 보니까 글이 길어질 수밖에 없었네요. 부족한 글 읽어주셔서 감사합니다. 좋은 밤 보내세요!
댓글
로그인 후 댓글을 남길 수 있습니다.
하 글을 쓰는게 쉬운 일이 아니네요 계속 다시 읽어보고 있지만 어떻게 잘 읽힐지 부족하지 않을지 모르겠습니다. 혹시 글을 읽으면서 이해를 못하겠거나, 부족한 부분이 있다면 알려주세요. 감사합니다