메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

디자인 패턴과 소프트웨어 구조

한빛미디어

|

2016-04-27

|

by 로버트 나이스트롬

13,669

왜 디자인 패턴인가?

 

프로그래밍 책 제목에 '패턴'이라는 단어가 들어 있다면 에릭 감마, 리처드 헬름, 랄프 존슨, 존 블라시디스(이들은 무시무시하게도 '4천왕'Gang of Four이라고 불린다)가 쓴 고전인 『GoF의 디자인 패턴』에 영향을 받았다고 보면 된다.

 

▼ 『GoF의 디자인 패턴』(프로텍미디어, 2015)

 

 

『게임 프로그래밍 패턴』을 책 제목으로 삼은 이유가 『GoF의 디자인 패턴』이 게임 개발에 맞지 않아서인 것은 아니다. 오히려 그 반대다. [[디자인 패턴 다시 보기]]에서는 『GoF의 디자인 패턴』에 나온 여러 디자인 패턴을 게임 개발에 어떻게 적용할 수 있을지를 다룬다.반대로 비-게임 소프트웨어 개발에도 이 책이 도움을 될 거라고 생각한다. 책 제목을 '디자인 패턴 확장판'이라고 할 수도 있었지만, 게임이 예제로 나오면 더 재미있을 거라고 생각했다. '직원 정보'니 '은행 계좌'같은 예제를 또 보는 건 지긋지긋하지 않나?이 책에 수록한 패턴들은 다른 분야에서도 유용하지만, 특히 다음과 같이 게임을 개발하면서 자주 하게 되는 고민들을 해결하는 데 적합하다.

 

  • 시간과 순서는 게임 구조의 핵심 부분이다. 사건은 올바른 순서로 적절한 시간에 발생해야 한다.
  • 개발 주기가 굉장히 빡빡하다. 여러 프로그래머는 다양한 기능을 빠르게 만들고 반복 개발하는 동시에 다른 개발자를 방해하거나 코드베이스를 더럽히지 않아야 한다.
  • 여러 기능이 모두 정해지고 나면 기능 간에 상호작용이 시작된다. 괴물은 영웅을 공격하고, 물약을 마시고, 폭탄은 적군, 아군을 가리지 않고 날려버린다. 이런 상호작용을 구현하는 동안 코드가 실타래처럼 엉키지 않게 해야 한다.
  • 마지막으로 게임에서는 성능이 굉장히 중요하다. 게임 개발자들은 누가 대상 플랫폼에서 성능을 최대한 쥐어짤 수 있는지를 두고 끊임없이 경쟁한다. 최적화 기법은 게임이 수백만 장 이상 팔린 AAA 성공작이 되느냐, 프레임은 뚝뚝 끊기고 악플이 쏟아지는 실패작이 되느냐를 가를 수 있다. 

 

좋은 소프트웨어 구조란?

 

무작정 패턴의 바다에 뛰어들기에 앞서, 소프트웨어 구조와 이를 게임에 적용하는 방법에 대한 내 생각을 먼저 공유하는 것이 책을 이해하는 데 도움이 될 거 같다. 하다못해 디자인 패턴과 소프트웨어 구조가 얼마나 끔찍한지(혹은 굉장한지) 논쟁이 벌어졌을 때 써먹을 논지를 무기로 얻을 수 있다.
이 책 어디에도 3D 그래픽스에 필요한 선형대수나 게임 물리에 필요한 미적분 내용은 나오지 않는다. AI의 탐색 트리에서 알파-베타 가지치기alpha-beta prune를 하는 방법이나, 오디오가 방 안에서 들리는 것처럼 반향 효과를 시뮬레이션하는 방법도 알려주지 않는다. 
대신 이 책은 그런 요소들 사이에 들어가는 코드에 대해 알아볼 것이다. '어떻게 코딩할 것인가'보다는 '어떻게 구조를 잡을 것인가'를 다룬다. 모든 프로그램, 심지어 'main() 함수에 전부 다 집어넣고 돌려보자' 식의 코드조차 어떤 식으로든 구조가 있다. 따라서 무엇이 좋은 구조를 만드는 지를 살펴보는 게 더 흥미로운 일이라고 생각한다. 좋은 구조와 나쁜 구조를 어떻게 구별할 수 있을까?
책 쓰는 5년 내내 이 질문을 고민해왔다. 어떤 게 좋은 구조인지 다들 느낌으로는 안다. 우리 모두는 엉망진창인 코드로 오랫동안 고통받았다. 엉망인 코드에 대해서 우리가 할 수 있는 최선은 (할 수만 있다면) 그 코드를 제거하는 것이다.
아름답게 구축된 코드에서 작업할 기회를 가진 운 좋은 사람도 몇몇 있을 것이다. 이런 코드베이스는 시설이 완벽하고, 어디에서나 종업원이 대기하고 있는 5성급 호텔 같은 느낌을 준다. 이런 차이는 어디에서 올까?나에게 좋은 구조란, 뭔가를 고쳐야 할 때 그럴 줄 알았다는 듯이 코드가 준비되어 있는 걸 의미한다. 즉, 코드를 거의 건드리지 않고도 적당한 함수 몇 개만 호출하면 원하는 작업을 할 수 있어야 한다.
말은 좋지만 '코드를 고쳐도 겉으로 봐서는 손 안 댄 것처럼 하기'란 현실적으로 쉽지 않다.
하나씩 나눠 생각해보자. 먼저 '구조는 변경과 관련이 있다'는 점이다. 누군가는 코드를 고쳐야 한다. 너무 완벽해서든, 너무 더러워서 누구도 보기 싫어서든 코드를 고칠 일이 전혀 없다면, 그 코드에 대한 구조는 고민하지 않아도 된다. 얼마나 쉽게 변경할 수 있느냐가 코드 설계를 평가하는 척도가 된다. 변화가 없는 코드는 출발선을 결코 떠나지 않는 달리기 선수와 다를 바 없다.
기능 추가, 버그 수정, 그 외 무슨 이유에서든지 간에 코드를 고쳐야 한다면, 먼저 기존 코드를 이해해야 한다. 전체 프로그램을 다 이해해야 하는 건 아니지만, 고치려는 코드와 관련된 부분은 머릿속에 집어넣어야 한다.
 

 

대부분 이 과정을 대수롭지 않게 여기지만, 사실 프로그래밍에서 가장 오래 걸리는 부분이다. 데이터를 디스크로부터 램으로 로딩하는 게 느리다고 하지만, 눈으로 코드를 읽어서 두뇌에 로딩하는 것에 비할 바가 아니다.
머릿속에 코드에 대한 큰 그림을 그리고 나면 해결책을 금방 찾을 수 있다. 시행착오를 여러 번 겪을 수 있겠지만, 이 과정은 비교적 수월하다. 일단 문제가 무엇인지, 어디를 고쳐야 할지를 이해하고 나면, 실제 코딩은 별것 아닌 경우가 종종 있다.
컴파일이 성공하고 원하는 대로 코드가 돌아갈 때까지 코드를 입력했다고 해서 끝난 건 아니다! 테스트 를 작성하고, 코드 리뷰를 요청하기 전에 코드를 정리해야 한다.
코드를 추가했다고 해서, 코드 곳곳에 우리가 남겨놓은 똥(?)에 다른 사람이 걸리적거리게 하고 싶진 않을 것이다. 사소한 변경이 아니라면, 추가한 코드를 나머지 코드와 깔끔하게 통합하기 위해 어느 정도 맞춰줘야 한다. 제대로 했다면, 동료들은 코드가 바뀌었는지조차 모를 것이다.
요약하자면, 프로그래밍 흐름도는 다음과 같다. 

 

▲ 프로그래머의 업무를 간단히 요약한 그림

(GET PROBLEM: 업무 할당 / LEARN CODE: 코드 파악 / CODE SOLUTION: 문제 해결 코드 작성/ CLEAN UP: 코드 정리)

 

 

나쁜 코드에도 장점이 있다

 

상황에 맞는 코딩 스타일이 따로 있다. 이 책의 대부분은 코드를 유지가능하고 깔끔하게 만드는 내용을 다룬다. 나는 '제대로' 만드는 것을 선호하는 편이지만, 엉성한 코드도 나름의 가치는 있다.
구조화가 잘된 코드를 작성하려면 많이 고민해야 한다. 즉, 시간이 필요하다. 더욱이 좋은 구조를 개발 기간 내내 유지하려면 엄청난 노력을 들여야 한다. '야영객이 야영장을 처음 왔을 때보다 더 깨끗하게 해놓고 떠나는 것' 처럼 코드를 다뤄야 한다.
오랫동안 같은 코드로 계속 작업해야 한다면 이렇게 하는 게 좋다. 하지만 앞서 얘기한 대로 게임을 기획하기 위해서는 실험과 탐구를 많이 해야 한다. 특히 초반에는 나중에 버릴 코드를 작성하는 일이 비일비재하다.
단순히 어떤 기획을 확인하기 위한 코드의 구조를 멋지게 만들려다가는 실제로 화면에 띄워서 피드백을 얻기까지 시간만 더 오래 걸릴 뿐이다. 기획이 별로라고 판명되면 코드를 우아하게 만드는 데 쏟았던 시간도 코드와 함께 버려진다.
기획 확인에 필요한 기능만 간신히 돌아가도록 대강 코드를 작성하는 프로토타이핑 기법은 아주 적법한 프로그래밍 습관이다. 다만 주의사항이 있다. 버릴 코드는, 나중에 확실히 버릴 수 있게 해야 한다. 다음과 같이 사람을 갖고 노는 상사를 여러 번 보아왔다.

 

팀장: "이번에 나온 기획을 테스트해보고 싶어. 어차피 프로토타이핑이니까, 대충 빠르게 만든다면 얼마나 걸릴까?"

팀원: "글쎄요. 테스트나 문서화 없이 버그가 많아도 상관없다면 날림으로 며칠 안에 임시 코드를 만들 수 있을 거 같네요."

팀장: "좋아. 그렇게 진행해줘."

 

며칠 후...

팀장: "프로토타입을 보니까 괜찮은 거 같아. 몇 시간만 더 써서 정리하면 출시용 작업물로 만들 수 있지?"

 

'버릴' 코드를 사용하는 사람들에게는, 코드가 동작하는 것처럼 보이더라도 유지할 수 있는 상태는 아니기 때문에 나중에 반드시 다시 만들어야 한다는 걸 분명히 주지시켜야 한다. 혹시라도 '버릴' 코드를 계속 유지해야 할 가능성이 있다면 방어적으로 잘 만들어야 할 필요가 있을지도 모른다.

 

TAG :
댓글 입력
자료실