객체지향의 사실과 오해(feat. 되돌아보기)

0_0_yoon·2021년 11월 30일
1


객체지향 프로그래밍의 대략적인 정보는 블로그나 유튜브에서 여러 번 접해봤지만, 책을 통해 기본 개념을 공부해보고 싶었다. 그 중 이 책을 추천받아서 읽어봤는데 내가 짠 코드에 의구심이 생긴 이유를 알게 됐다.
첫 번째 이유는 내가 객체를 독립적으로만 바라봤기 때문이었다. 엥 이게 무슨 말인가? 객체지향 프로그래밍 하는데 객체를 독립적으로 바라보는 게 무슨 문제인가? 그렇다. 문제는 없다. 하지만 여기서 중요한 점은 객체를 동적으로 봐야 한다는 점이다. 클래스는 정적이지만 객체는 동적이다. 나는 처음에 동적인 객체들이 서로 협력하며 기능을 구현하는 모습을 상상하며 설계하고 구현했는데 내가 정작 코드를 바라볼 때는 정적인 클래스만을 바라보니 문제가 된 것이다. 객체들이 서로 협력하고 한 객체가 다른 객체의 활동을 제어, 조율하고 결합되는 것은 당연하다.나는 이를 통해서 객체지향 프로그래밍을 하며 어떻게 코드를 바라보면 될지 감을 잡을 수 있었다.
두 번째 이유는 기능 중심적으로 설계했기 때문이다. 이 말만 보면 이것도 틀린 말이 아니다. 하지만 여기서 간과된 점은 "구조" 다. 나는 기능만을 염두하고 설계했다. 구조는 설계를 끝내고 구현하는 단계에서 그럴듯하게 짜 맞췄다. 그 결과 내 코드를 보면 구조적인 체계가 전혀 잡히지 않았기 때문에 변경사항이 생긴 경우에 어디서부터 손을 대야 할지 감을 잡을 수 없던 것이다. 이에 대한 방안은 당연히 기능과 함께 구조도 같이 설계하는 것이다. 좋은 구조에서 코드를 짠다면 변경사항에 유연하게 대처할 수 있다. 좋은 구조를 짜는 힌트는 밑에서 이야기하겠다.
기존에 있던 의구심을 해소하고 또 다른 수확으로는 설계 단계를 어떻게 접근하면 좋을지 알게 된 것이 있다. 내가 나름대로 이해한 부분을 설계의 순서대로 정리를 해봤다.


1. 현실에서의 객체와 소프트웨어에서의 객체 차이를 인지 하자

현실 객체와 소프트웨어 객체는 은유를 통해서 시스템을 이해하는 데 도움을 줄 수 있다. 하지만 그게 끝이다. 메뉴판을 예로 들자면 현실 세계의 메뉴판은 사용자에 의해서 사용될 뿐 자의적으로 어떠한 행동도 할 수 없다. 그러나 소프트웨어의 세계에서는 사용자 객체가 요청하면 메뉴판은 하나의 자율적인 객체로써 응답을 할 수 있다. 지금까지 나는 현실 세계를 투영한 객체들을 후보로 삼아 선택을 고민했는데 이제는 여의찮다면 아예 창조하는 것도 방법이라는 것을 알게 됐다.

2. 기능과 구조를 설계하자

위에서 한번 언급한 내용인데 나에게 이 부분이 가장 큰 도움이 될 것 같다.

2-1. 사용자 입장에서 필요한 기능을 작성하자

뒤에 나오겠지만 여기서 작성한 기능들은 여러 단계를 거치며 마지막엔 객체의 인터페이스를 결정하는 데 사용된다. 사용자 입장에서 기능을 작성하면 어떤 목표를 위해서 시스템이 어떻게 할지가 아니라 무엇을 해야 하는지를 표현하게 되므로 뒷 단계에서 객체의 행위를 캡슐화하기에 쉬워진다. 다시 말하자면 사용자 입장에서 기능을 작성함으로써 시스템의 입장에서는 기능이 책임으로 바뀐 것이며 이를 통해 행위를 캡슐화를 할 수 있다.

2-2. 도메인 모델을 기반으로 안정적인 구조 위에서 설계하자

위에서 언급했던 좋은 구조를 짜는 힌트는 바로 도메인 모델을 기반으로 설계하는 것이다. 도메인 모델은 일반적으로 사람들의 머릿속에 들어있는 공유된 멘탈 모델 (예를 들어 은행 또는 카페를 상상했을 때 떠오르는 개념들)을 의미한다. 도메인 모델을 구성하는 개념 간의 관계가 비즈니스 규칙을 기반으로 하므로 비즈니스 정책이 크게 변경되지 않는 한 안정적으로 유지된다.

3. 작성한 기능을 기반으로 객체 자체가 아닌 객체의 협력을 설계하자

기능은 객체 간의 협력의 산물이라고 볼 수 있다. 그래서 당연히 기능과 하나의 객체 자체를 대응시키는 것은 부자연스럽다.설계한 협력 속에서 메세지를 추출하자 이때 메세지는 너무 추상적이거나 반대로 너무 구체적으로 정하지 않고 현재의 문맥에 적합하게 한다. 처음에 기능을 작성했던 것처럼 마찬가지로 어떻게 할지가 아니라 무엇을 해야 할지를 표현하게 한다.

4. 메세지를 받을 수 있는 객체를 도메인 모델에서 추출한다.

여기서 포인트는 객체에 적합한 메세지를 찾는 게 아니라 메세지에 적합한 객체를 찾는 것이다. 그 이유는 간단하다. 객체에 메세지를 보내서 협력을 유도해 기능을 구현하기 때문에 메세지가 핵심이지 객체 자체가 핵심이 아니기 때문이다. 메세지를 먼저 선택하게 되면 객체의 내부구조를 신경 쓰지 않은 상태에서 송신자와 수신자가 느슨하게 결합되며 수신자 객체의 자율성을 보장한다.

5. 메세지를 통해서 객체의 인터페이스를 구성하자

여기서 객체의 속성이나 자료구조는 고려하지 않는다. 설계 작업은 구현을 위한 스케치를 작성하는 단계지 구현 그 자체일 수는 없다. 코드를 구현해서 설계에 이상이 없는지 구현 가능한지 판단해야 한다.


앞으로 이번에 이해한 내용을 의식적으로 되뇌며 적용해보고 수정하고 보완해나가야겠다.

profile
꾸준하게 쌓아가자

0개의 댓글