디자인 패턴이란?
디자인 패턴
디자인 패턴, 프로그래밍 패턴등으로 불리며 많이 사용되는 패턴
자체를 의미한다.
효율성, 가독성, 공간등이 월등하게 좋아지는 경우도 있으며 상황에 맞게 해당 패턴을 구사할 수 있다면 좋은 결과가 나온다.
코드를 엉망으로 짜다보니 이 책이 간절해졌다..
디자인 패턴 또는 프로그래밍 패턴은 중복되는 코드를 효율적인 해결책이다.
많은 사람들이 말하길 ‘효율적인 코드를 만들기위한 방법론’정도로 설명한다.
게임에 적용되는 디자인 패턴의 종류도 매우 다양하지만 그 활용도가 매우 높아서 필수적으로 활용해야 한다고 본다.
앞으로 게임프로그래밍 패턴에 대해서 공부하며 포스팅할 예정인데, 해당 예제는 C++
로 이루어져 있기 때문에 내가 예제를 C#으로 만들어 유니티로 테스트해볼 예정이다.
카테고리가 C#인 이유.. 직접 변형해가면서 필요한 상황을 익히려고 한다..
구조
소프트웨어에서 구조란, 코드를 어떤식으로 구성하는지에 대한 말인 것 같다.
내가 지금짜고 있는 구조가 좋은 구조인지 안좋은 구조인지는 짜는 본인이 알고있으며 조금 더 좋은 구조로 변경할 수 있음을 아는게 중요하다.
또한, 내가 코드를 수정하고자 한다면 해당 코드의 구조를 파악해야 한다.
이 과정은 아직도 많이 부족함을 알지만 다른 사람의 코드를 보고 해석하는 능력은 정말 반복의 연속이라는 생각이다.
문제를 해결하기 위해서 코드를 추가한다고 해도 해당 코드가 다른 코드들과 영향이 없고 독립적으로 잘 돌아간다면 문제가 없지만, 코드한줄로 프로그램이 망가질 수 있기 때문에 구조피악하는게 중요하다.
디커플링
간단하게 말해서 플레이어와 함정의 관계정도로 생각하면 이해가 잘된다.
책에서는 양쪽 코드중에서 한쪽이 없다면 다른 한쪽 코드를 이해할 수 없는 것을 커플링
이 코드를 디커플링하게 된다면 한쪽 코드만 있어도 해당 동작을 이해할 수 있다.
앞서 디커플링에 대해서 설명한 이유는 코드의 이해단계(구조파악)가 매우 줄어든다는 점이다.
또한, 코드의 추가부분도 줄어들게 된다.
한코드를 변경했다면 다른 코드도 연결지어서 변경해야 하지만, 커플링이 적은 코드라면 게임에 미치는 요소 또한 줄어들게 된다.
이러한 요소 때문에 디커플링패턴이 많이 사용되며 요소가 되는 추상화, 모듈화, 디자인패턴, 소프트웨어 구조가 각광받는다.
같은 기능을 하는 프로그램이라도 독립성이 보장된다면 이해와 수정이 정말 빠르게 이루어지기 때문에 생산성이 높아진다.
하지만 그만큼 코드의 구조를 잡는 일은 매우 어렵다..
많은 사람들이 확장하기 쉬운 코드베이스(ex. 완벽한 부모클래스..같은?)를 갈망하지만 이 부분자체가 예측
이라는 항목이 들어가기 때문에 디버깅과 유지보수에 그만큼의 시간을 할애한다.
확장성(일반화)에 심취하게 되면 인터페이스, 추상화, 가상메서드 등등 확장포인트가 늘어나게 되면서 구조 자체가 망가지게 될 수 있다.
커플링 패턴을 피해서 디커플링을 추구하지만 망상 추상화계층에 먹히고 마는 것..
성능 그리고 속도
혹자는 소프트웨어의 구조 그리고 추상화가 오히려 게임의 성능을 제한시킨다는 비판을 한다.
코드 자체를 유연하게 하는 가상함수, 인터페이스, 포인터, 메시지등 같은 메커니즘에 의존하지만 다들 어느정도 런타임비용을 요구 한다.
이 때문에 성능이나 속도를 고려한다면 예측
그리고 가정
이 매우 중요하다.
모든 개체가 같은 클래스라고 한다면 배열에 집어넣어서 깔금하게 사용하거나 한가지 자료형이 한가지 메서드만 호출한다면 정적으로 바인딩된 메서드를 호출하는 방법이 있다.
이러한 견해나 사례로 유연성 자체가 나쁘다는 점을 피력하는 것이 아니라 구조자체를 만들 때 무조건적으로 좋다는 것이 아니라는 것을 말해준다.
이러함을 알아도 유연성을 포기하지 못하는 이유는 개발속도 그리고 확장성 측면에서 비약적으로 좋기 때문이다.
ps. 책에서 추천하는 방법으로 처음에는 유연하게 코드를 유지하다. 기획이 확실해지면 추상계층을 제거해 성능을 높이는 방법이 있다.
나쁜코드
좋은 코드는 구현함에 있어 시간이 오래걸린다. 해당 코드에 대한 유지성, 확장성을 고려해야하기 때문.
나쁜 코드는 지금 당장의 기능을 실행하기 위해서 만드는 코드를 예로 들 수 있다.
프로토타입을 구현함에 있어, 기능적인 부분만 보여주기 위해서 만들었다고 한다면 유지할 수 있는 상태가 아니기 때문에 반드시 다시 만들어야한다.
따라서 나쁜코드(버릴코드)를 작성하더라도 유지해야할 가능성을 봐야한다.
균형 잡기
게임을 완성하는데 있어서 가장 좋은 목표를 예로 든다면 아래와 같다.
- 프로젝트 개발 기간동안 코드를 쉽게 이해할 수 있도록 구조를 깔끔하게 만들고 싶다.
- 실행성능을 최적화 하고 싶다.
- 지금 개발 중인 기능을 최대한 빠르게 구현하고 싶다.
목표는 매우 달콤해보이지만 어느정도 서로에게 상반된다.
좋은 구조는 장기적으로 생산성을 높여주지만 구조를 좋게 유지할려면 코드를 변경할 때 마다 노력을 더욱 해야한다.
최적화에는 매우 많은 시간이 소요되기 때문에 빠르게 구현한 결과물이 좋은 실행속도를 내는 경우는 드물다.
또한 최적화가 매우 잘된 코드들은 유연하지 않아서 고치기가 어렵다..
세가지 목표 각각의 장단점이 확실하기 때문에 우리는 적절한 균형을 잡아야 한다.
단순함
위의 문제를 조금이라도 쉽게 바라볼 수 있는 수단은 단순함
이다.
코드를 작성할 때 코드를 최대한 단순하고 간결하게, 문제를 해결하는 방향으로 짜게되면 코드만 읽어도 의도를 쉽게 파악할 수 있고 그외 다른 방법이 떠오르지 않는다.
전체적인 코드의 양이 줄어들고 본인이 생각해야하는 양또한 줄어들게 된다.
이러한 코드를 짜는 팁은 필요없는 코드를 빼는 것 부터 시작한다.
마무리
정리하며 읽는 내내 정말 내가하고 있는 고민들을 다들 하고 있다는 점에서 놀랐고, 내가 그동안 외면했던 문제들을 직면할 수 있어서 좋았다..!
- 추상화와 디커플링을 잘 활용하면 코드를 점차 쉽고 빠르게 만들 수 있다. 하지만, 지금 고민중인 코드에 유연함이 필요 없다면 디커플링과 추상화를 적용하느라고 시간낭비하지 말자..!
- 개발 내내 성능을 고민하고, 최적화에 맞게 설계해야한다. 하지만 가장 자체를 박아두는 저수준의 최적화는 가능하면 늦게해라
- 게임 기획에 맞추느라 코드를 엉망으로 만들지 말자, 그 코드로 작업하는 것은 본인이다.
- 뭔가 재밌는 걸 만들고 싶다면 만드는 데에서 재미를 느껴라
이 포스팅은 저자: 로버트 나이스트롬 옮김: 박일
게임 프로그래밍 패턴책을 참고하였습니다.
댓글남기기