|
개발 카테고리에 진지하게 글을 쓴 게 꽤 오래됐네요. 일단 블로그에 글을 쓴 것 자체가 굉장히 오래되었으니 당연하긴 한데…. 쓰자고 생각을 하고 보면 별 대단한 내용 아니긴 해도 현재 개발중인 프로젝트의 보안에 직결된 내용이 많은지라 쉽게 쓰질 못 했는데, 올해부터는 간간히 공개할 수 있는 것들은 공개하는 게 어떨까 생각하고 있습니다. 그 첫 번째 이야깃 거리로….
굉장히 오랜 시간 동안 고민했던 것 중의 하나가 게임 로직에서 사용할 객체 시스템에 관한 것이었습니다. 요즘은 많은 게임에서 엔티티-컴퍼넌트 모델을 채택하지요? 이전 프로젝트를 진행하면서도 컴퍼넌트 개념을 도입하려고 시도를 했었는데, 당시엔 내공이 절대적으로 부족했던 탓에 결과적으론 주화입마에 빠진 것 같고…. 이번 프로젝트에서는 그런 전철을 밟지 않기 위해서 꽤나 고민을 많이 했습니다. 오랜 시간 저를 괴롭힌 주된 고민 중의 하나는 컴퍼넌트 모델에 항상 따라오는 메시지라는 개념이 암만 생각해도 컴퍼넌트 모델과 어울리지 않는다는 것이었습니다. 좀 더 정확히 의문을 구체화하자면, '컴퍼넌트에 메시지를 보낸다는 게 실제로 그 컴퍼넌트의 함수를 직접 호출하는 것과 근본적인 차이가 있나?' 이런 거였죠. 이어지는 잡스러운 이야기▼ 메시지란 게 특정 컴퍼넌트에 대한 컴파일 타임 의존성을 갖지 않게 만들어주는 건 사실이지만, 실제로 특정 컴퍼넌트가 다른 컴퍼넌트에게 어떤 메시지를 보내는 함수를 갖고 있다고 치면, 그 메시지를 발신한 컴퍼넌트는 특정 수신자가 특정 메시지를 받아서 처리할 수 있다는 사실을 알고 있단 얘기잖아요? 형식적으로는 의존 관계가 없지만, 사실은 발신자는 수신자가 어떤 메시지를 받을 수 있는가, 어떤 기능을 갖고 있는가에 대한 지식 수준에서 의존성을 갖게 된다는 얘기죠. 즉 컴퍼넌트 모델이라는 접근의 가장 큰 장점이 게임의 객체를 구성하는 구성 요소간의 의존성을 최소화해서 수정에 닫힌 객체로 만들어 유지 보수성을 높이는 것이라고 볼 때, 다른 컴퍼넌트가 이 메시지를 수신할 수 있다는 지식을 갖고 있다는 사실은 컴퍼넌트를 충분히 수정에 닫힌 객체로 만들 수 없게 하는 것 아닌가, 하는 게 고민이었는데요, 메시지가 체이닝되면 상황을 더욱 나빠집니다. 이벤트를 사용하면 이쁘게 해결할 수 있으므로 작위적인 예제이긴 합니다만, 마우스로 클릭해서 인벤토리에 아이템을 추가하는 상황에, 마우스 컨트롤 컴퍼넌트가 로직 인벤토리 컴퍼넌트에 아이템 추가 메시지를 보내고, 그 이후에 로직 인벤토리가 프리젠테이션 인벤토리에 이미지 추가 메시지를 보내는 상황을 상정해보면, 전체적인 로직 진행 과정을 파악하는 것은 매우 힘들어집니다. 오랜 고민 끝에 2008년 초, 문제 해결의 단초를 <엔터프라이즈 아키텍처 패턴>이라는 책에서 소개하는 도메인 모델이란 개념에서 발견했습니다. 사실 정확히 도메인 모델과 일치하는 해결은 아닌데, 해결책의 요지는 이렇습니다. 컴퍼넌트를 다른 컴퍼넌트와 의존성을 갖는 연산이나 자명하지 않은 조건 검사 등을 전혀 포함하지 않은 채로 필수적인 최소한의 연산만 구현해서 완결합니다. 예를 들어 로직 인벤토리가 하나의 컴퍼넌트라고 치면 아이템을 넣고 빼는 연산과 자리가 비어서 아이템을 넣을 수 있는지, 아이템이 있어서 꺼낼 수 있는지 확인하는 함수 외에는 아무 것도 구현하지 않는 것이죠. 그러면 도대체 인벤토리에 아이템을 넣으려면 어떻게 하잔 거냐? 여기에 트랜잭션 객체란 개념을 도입합니다. 마우스 컨트롤러 컴퍼넌트가 인벤토리 컴퍼넌트에 메시지를 보내는 게 아니라, 트랜잭션 객체 생성자가 업데이트 과정에 마우스 컨트롤러를 확인해서 아이템을 인벤토리에 넣어야겠구나, 이런 생각이 들면 아이템을 커서에서 꺼내서 인벤토리에 집어넣는 트랜잭션 객체를 생성해서 트랜잭션 큐에 밀어넣는 겁니다. (아까도 언급했 듯이, 로직 인벤토리가 노출하는 아이템 추가됨 이벤트에 프리젠테이션 인벤토리가 자신을 등록하는 게 훨씬 이쁩니다만 설명을 위해서) 이 트랜잭션 객체는 1. 원본 로직 인벤토리에서 아이템을 제거하고, 2. 원본 프리젠테이션 인벤토리에서 아이템 이미지를 제거한 뒤에, 3. 커서 컴퍼넌트에서 프록시 아이템을 제거하고 4. 타겟 로직 인벤토리에 아이템을 추가하고, 5. 타겟 프리젠테이션 인벤토리에 아이템 이미지를 추가하는, 다섯 가지 단계로 구현할 수 있을 겁니다. 트랜잭션 객체를 도입하면 각각의 컴퍼넌트는 임의의 트랜잭션 객체를 구현하는데 필요한 최소한의 연산만을 구현하면 땡이기 때문에 전혀 수정이 필요없으므로 수정에 닫혀있어야 한다는 조건을 만족하는 동시에, 새로운 기능의 추가는 새로운 트랜잭션 객체의 구현으로 깔끔하게 해결할 수 있으므로 확장에 열려있어야 한다는 조건도 만족할 수 있습니다. 요는 어떤 기능의 개념에 대한 지식은 컴퍼넌트에, 컴퍼넌트 간의 관계와 작업 절차에 관련된 지식은 트랜잭션 객체에 모으는 것인데, 이로써 컴퍼넌트와 트랜잭션 객체 모두 단일책임 원칙(Single Responsibility Principle)과 개방-폐쇄 원칙(Open-Closed Principle)을 잘 지킬 수 있게 되지요. 트랜잭션 객체 역시 메시지와 유사한 속성을 가지고 있기 때문에 메시지를 사용하는 컴퍼넌트 모델과 마찬가지로 서버-클라이언트 모델에도 잘 어울리고, 멀티 스레딩 모델에도 문제없이 대응됩니다. 꽤 오랜 시간 고민하면서 개발중인 코드에 적용해 본 결과 큰 구멍없이 게임을 완성할 수 있겠다는 확신도 얻었습니다. 요는 컴퍼넌트 모델을 고려하시는 분들께서는 메시지 핸들링 루틴을 컴퍼넌트에 포함시키는 대신에 트랜잭션 객체의 도입을 한 번쯤 고려해보시는 것도 나쁘지 않을 것 같을 것 같습니다- 뭐 이런 얘기네요. 물론 실제로 구현 수준으로 들어가면 트랜잭션 객체를 생성하는 놈은 도대체 정체가 뭐냐, 트랜잭션 객체간에 네스팅은 어떻게 해결해야 하나, 트랜잭션을 수행할 수 있는지 검증하는 프리디킷을 어떻게 정리할 것인가 등등에 대한 고민이 좀 더 필요합니만.
|
포토로그
카테고리
이전블로그
최근 등록된 덧글
최근 등록된 트랙백
메뉴릿
이글루링크
없음
▒ 제닉스의 사고뭉치 ▒ 뭉시리의 집.. Mii Plluto's cheerful Geh.. 일본에 먹으러가자. Sequoia WebLog the world is naked. 태양의 곁자리 하얀까마귀의 테스트베드.. v e r . b e t a 주식회사 이디스 sphere burster ; whit.. gundown의 食遊記 LOVEstation AD/DA -.. I Hate You 이은석 항해일지 soup_box[물고기.. 히엔 돈 카펠리아노 산벽달회 나를 숨기는 것은 얼마나.. ozzyz review 허지웅.. ▷단열 곤충 채집통◁ sIMAGINATIONs ZELONGLOO3OTH Groove Tube P.C하지 않은 ㅎㅅㅎ 25세 빛의 탑, 어둠의 던전 紙月 오리대마왕님 집 Field's Nest Astralium Report rehn's トイレ kyungjae.net 사회디자인연구소 Blameless life.... 龍孤視遠天爲時振威名 카즈군의 Holyland ROUGH SKETCH ▣Lac pourpre▣ Oxymoronic World 우리는 꽁패밀리!!!! 한글날의 부활. 쌀밥게임 대왕 gimmesilver's blog 무디의 무책임한 세상 Discoveries Noenoe Sweet & Slow ZelDaQ 빈틈씨의 먹자골목 You're on the blitzkre.. 매거진 프라우드 MAGAZ.. CASSIS PEACH 랩좀비. 랩은 못하지만 .. rootrain '-')/ 毎日がスペシャル 마나네 타이요(taiyo) 쑥의 pro.TOT.yping Relish the Process 정열의 아자베 둥글게 君という光 rose 구찮아... Stay hungry, stay fo.. 깔짝깔짝 생활 Dream of Time 얼어붙은 수돗물 파이프 낭만과 해학으로 함께 가.. 쳐키의 드라이빙 Ohyecloudy's S3 Counter-revolutionar.. 도로시를 부탁해 ★ Stella et Fossilis SAGA 완성의 그 날 M과 M사이 Incarnation 카로 택시지 Li ucciderò. 망치와 모루 마케터의 블로그스타 - 200.. ANTHOLOGY 2731A 공돌이 옵빠 K 송아지 스팀밀크 백기사님의 이글루 grand blue 따뜻하고 한가로운 블로그 하드보일드하게 사는 거야! 야재나라 야햑묜 이글루 바깥 세상
|