나는 이것을 첫번째 프로젝트 진행 중에 깨닫게 되었다. 1942 게임을 만드는 중에, 연산과 출력, 즉, 비행기의 이동과 비행기의 그림 출력을 하나의 Loop 안에 넣고 돌리고 있었다.

처음, 비행기의 이동과 비행기의 출력을 하나의 함수안에 하나의 루프안에 넣고 나서, 비행기의 이동에 따른 출력을 정상적으로 처리 했으나, 추가적으로 총알의 출력을 처리해야 될 때, 함수 안이 점점 복잡해 졌다. 명언 중에, 바보는 복잡한 것을 무시하고, 현실주의 자는 복잡한 것을 피하거나 괴로워 하고, 천재는 복잡한 것을 없앤다 - 앨런 펄리스가 했던 것이 기억이 난다.

바로 이런 상황이 "복잡한 것" 이다. 복잡한 것은 어디를 수정하든, 다른 곳도 수정해야 "정상적"으로 되는 상황을 뜻한다. 이게 물의 파장처럼 계속 퍼지면, 결국 .. 비야네 스트롭스트룹이 말한데로, 4번은 갈아 엎어야 되는 상황이 발생하는 것이다.(이건 리팩토링과 같은 의미이다.)

결국 전부 뜯어 고쳐서, 연산은 연산만 하고, 출력은 연산 결과를 얻어오는 함수를 통해서, 출력만 하게 바꾸고, 총알 역시, 연산은 연산만 하고, 여기에 따른 결과를 얻어 출력만 하게 되니, 무척 깔끔해 지고, 유지 보수가 무척 깔끔해 지는 효과를 보게 되었다.

그 후에, 이 말의 의미를 확실하게 인지하고 있었으나, "무엇을 하나의 역활로 봐야 하는가?" 에 대한 스스로의 질문에, 답을 내지 못하고 있다가, "절대적으로 하나의 역활로 봐야 하는것이 무엇인가?" 란 질문으로 스스로 답을 냈다.

그 답은, 입력과 연산과 출력은 하나로 묶어서 쓰지 말것, 생성자에서 많은 일을 하지 말고, 특정 함수를 만들어 초기화 시킬 것, 소멸자도 마찬가지, "행동"으로 간주 될 수 있는 것은 함수로 빼서 사용할 것, 이다.


이건 뭐 내 경험이고, 책의 내용 중, 예를 옮긴다.

  • 예 1 : realloc 의 역활을 아는가? 여기에는 수 많은 역활을 이 함수 하나에 다 짚어 넣은 결과 "잘못된 디자인의 상징"으로 꼽힌다.
  • 예 2 : basic_string 의 클래스를 보았는가?, 멤버 함수만 100개가 족히 넘는다. 역시 "비효율적인 클래스 디자인의 상징"으로 꼽힌다.

총평

이것은 진리라고 봐도 된다. 일상 생활의 예를 들면, 친구 A, B, C 와 각각 다른 이야기를 동시에 하면, 결국 각각 집중 할 수 없어서, 머리속엔 "내가 무슨 이야기를 하고 있는 거지?" 란 꼴이 되고야 만다.


posted by 농사를 짓는 게임 프로그래머 최익필

댓글을 달아 주세요