객체지향에 대한 오해
객체지향의 목표는 실세계를 모방하는 것이아니다(설명하는데 도움은 되지만 똑같이 만들어야 좋다는 사실은 오해다) 실세계를 은유하는 것이다.
객체지향은 클래스가 아니다. 객체지향을 구현하는 방법중에서 클래스가 중요하게 다루어지는 것 뿐이다. javascript의 prototype으로 객체지향을 구현할 수도 있다.
책임주도설계
객체지향적으로 사고할 때 보통 클래스를 만들어놓고 어떤 클래스가 어떤 역할을 할지 생각하는 경우가 많은데, 오히려 그 반대의 경우가 효과적이다.
객체와 객체는 메시지를 통해 협력한다. 메시지를 먼저 찾고, 어떤 객체에게 메시지가 전달될지 찾는 것이 합당하다. 이것을 책임-주도설계라고 한다. 우리가 익히 아는 TDD도 마찬가지다. TDD는 test를 먼저 작성하며 어떤 메시지를 어떤 객체에 할당할지 미리 생각하게 된다. 하지만, TDD는 초보자가 하기에는 어렵고 숙련자에게 맞는 방법이다.
예를 들어 커피를 주문한다고 생각해보자.
손님은 바리스타에게 커피를 만들어달라(아메리카노) - method(argument) - 고 메시지를 전달하고 바리스타는 커피를 만든다. 커피에는 아메리카노, 카푸치노, 카페라떼 등 여러커피가 있겠지만, 복잡성을 덜기 위해 그냥 전부 추상화하여 커피라는 타입으로 생각한다.생각한다. 바리스타가 커피를 만드는 방법은 바리스타의 자율성에 맡긴다. 어떻게 만들던지, 만들어 주기만 하면된다. 손님은 그것을 알 필요가 없다. 바리스타의 역할인 커피를 만든다와 책임인 어떻게가 분리된 것이다.
역할과 책임의 분리되면 자율성이 확보되고 이러한 코드는 코드의 결합도를 떨어뜨리고 응집도를 높여 유연한 코드를 만들 수 있다. 역할은 interface의 형태로, 책임은 imple의 형태로 나타난다.
또 바리스타가 커피를 만들 때 누군가 얼음을 넣고 샷을 넣고 .... 순서대로 하라고 지시하지 않는다. 어떻게 만들던지 다른 객체가 알아서는 안된다. 바리스타의 자율성에 맡겨야 유연한 코드가 만들어질 수 있다.
얼음을넣고, 샷을 넣고 ... => 커피를 만들어라
이렇게 메시지를 적절한 레벨이서 추상화하고, 나머지는 바리스타가 알아서 하도록 한다.
도메인
요구사항이 바뀌는 일은 언제나 있는 일이다. 훌륭한 설계자는 요구사항 변화에 민첩하게 반응하며, 미래의 변화를 예측하지 않고, 미래의 변화를 대비할 뿐이다.
기능이 아니라, 구조를 기반으로 설계해라. 전통적인 기능 분해는 기능을 중심으로 설계하는 것을 말한다. 이 방법은 기능을 분해하여 설계하는데, 기능에따라 구조가 따라가게 되는데 기능은 원래 잘 변하기 때문에 한번 변하면 구조도 크게 요동친다. 대신 잘 변하지 않는 구조를 중심으로 설계하라.
구조는 도메인 모델로 나타낼 수 있다. 도메인 모델은 문서나 다이어그램이 아니라, 사람들의 머릿속에 들어있는 공유된 멘탈모델이다. 도메인 모델을 기반으로 시스템의 기능을 구현해야 한다. 도메인 모델과 코드를 밀접하게 연관시키기 위해 노력하라. 코드로부터 도메인이, 도메인으로부터 코드가 유추될 수 있도록 해라. 그러면 기능은 모델을 따라 자연스럽게 흘러갈 것이다.