객체 지향의 사실과 오해

객체지향이라는 것이 무엇일까?
객체지향 프로그래밍을 수행하고 있는 개발자들조차 이 물음에 명확한 답을 바로 내놓지 못한다.
객체지향이 말 그대로 객체를 지향한다는 것을 이미 알고 있으면서도, 나를 포함하여 대부분의 사람들은 이를 클래스나 상속 등 구현 관점에서만 바라보는건 아닌가 싶다.
이런 좁은 시야로만 바라본다면 객체지향의 본질을 이해할 수 없을 것이다.

필자는 객체지향으로 향하는 첫 걸음은 클래스가 아니라 객체를 바라보는 것으로부터 시작한다고 말한다.
그리고, 객체를 각각의 독립적인 존재로서 바라볼 것이 아니라, 전체 소프트웨어 기능을 구현하기 위해 서로 유기적으로 협력하는 공동체의 존재로 보아야한다고 말한다.
이러한 공동체의 일원으로 참여하는 객체들에게 설계자가 얼마나 적절한 역할과 책임을 부여하는지에 따라 설계의 성패가 달려 있다. 객체지향 프로그래밍이라는 것은 결국 이러한 객체들의 역할, 책임, 협력 관계를 프로그래밍 언어라는 틀에 잘 담아내는 것을 의미한다.

객체를 실세계의 투영 및 모방만으로 이해하는 것은 부족함이 있다.
객체지향의 목표는 실세계를 모방하는 것이 아니다.
오히려 실세계보다 더 넓은 신세계를 창조하는 것이다.
그럼에도 사람들이 반복적으로 객체를 실세계와 연결하여 바라보는 이유는 이러한 방법이 객체를 아주 쉽게 이해할 수 있는 수단이기 때문일 것이다.
필자는 재밌는 ‘이상한 나라의 엘리스’ 이야기를 통해 객체들의 의인화, 은유 과정을 설명한다.
한낱 납작한 종이 쪼가리에 불과한 트럼트들이 이상한 나라에서는 왕, 왕비, 신하, 증인 등 나름대로의 책임을 부여받고 마치 영혼이 있는 사람처럼 행동하고 말한다.
우리가 만드는 객체들도 모두 (그것이 무엇이건) 마치 인간처럼 자율성을 가지고 자신에게 부여된 책임을 다하려고 노력해야 한다. 객체는 실세계의 물리적인 실체를 가진 것들 뿐 아니라, 우리가 상상하고 경계 지을 수 있는 모든 것이라고 이해할 수 있다.
이러한 객체들은 자신만의 구분된 책임, 역할을 부여받고 이러한 책임을 수행하기 위해 자신만의 자율적인 방법으로 책임을 실현(구현)한다.

이렇게 객체가 수행할 수 있는 책임은 외부에 ‘공용 인터페이스‘라는 방식으로 공개된다.
외부 객체는 이러한 인터페이스를 통해 책임을 가진 객체에게 ‘메시지‘를 통해 요청을 전송한다.
(메시지는 구현에서 메서드로 이해할 수 있다.)
메시지를 수신한 객체는 해당 요청을 처리할 책임을 가진다.
하지만, 구체적인 수행 방법은 자신이 선택할 수 있는 자율성을 가진다.

‘카페’라는 소프트웨어 세계를 예로 들어 보자.
카페에서 ‘바리스타’라는 객체는 특정 커피 주문을 받고 커피를 만드는 책임을 가지고 있다.
‘손님’이라는 객체는 ‘바리스타’라는 객체가 공개한 ‘커피를 주문한다’ 라는 인터페이스를 통해 ‘바리스타’ 객체에게 ‘커피 주문’ 메시지를 전송한다.
하지만, ‘바리스타’ 객체는 커피를 만드는 책임을 수행할 때 구체적인 방법은 자신이 선택할 수 있다.
기계를 이용할 수도 있고 또는 자신이 직접 드립을 통해 생산할 수도 있다.
‘손님’ 객체는 요청한 것에 대한 정확한 응답만 얻으면 된다.
따라서, ‘바리스타’ 객체가 어떤 방식으로 커피에 대한 주문을 처리하는지는 관심도 없고 관심을 가질 필요도 없다.
이러한 객체의 자율성은 향후 소프트웨어의 변경을 최소화하고, 객체들의 소통과 협력을 유연하게 하는데 대단히 중요하다. 외부(인터페이스)와 내부(구현)을 적절히 분리하여 객체의 자율성을 부여하면 내부의 변경에 대해 외부 객체가 신경쓸 일이 없기 때문이다.

널리 알려진 미신과 달리 객체지향의 핵심은 클래스가 아니다. 핵심은 적절한 책임을 수행하는 역할 간의 유연하고 견고한 협력 관계를 구축하는 것이다. 클래스는 협력에 참여하는 객체를 만드는 데 필요한 구현 메커니즘일 뿐이다.

객체지향의 사실과 오해 p.38

객체지향을 통해 애플리케이션을 설계하려면 어떤 절차가 가장 효과적일까?
어떻게 설계해야만 사용자의 요구를 만족시킬 수 있는 기능을 제공하는 동시에 이해하기 쉽고, 단순하며, 유연한 상호작용을 제공하는 객체들의 공동체를 구축할 수 있을까?

올바른 객체를 설계하기 위해서는 먼저 견고하고 깔끔한 협력을 설계해야 한다.
협력을 설계한다는 것은 설계에 참여하는 객체들이 주고받을 요청과 응답의 흐름을 결정한다는 것을 의미한다.
이렇게 결정된 요청과 응답의 흐름은 객체가 협력에 참여하기 위해 수행될 책임이 된다.
일단 객체에게 책임을 할당하고 나면 책임은 객체가 외부에 제공하게 될 행동이 된다.
협력이라는 문맥에서 객체가 수행하게 될 적절한 책임, 즉 행동을 결정한 후에 그 행동을 수행하는데 필요한 데이터를 고민해야 한다.
그리고 객체가 협력에 참여하기 위해 필요한 데이터와 행동이 어느 정도 결정된 후에 클래스의 구현 방법을 결정해야 한다. 결과적으로 클래스와 데이터는 협력과 책임의 집합이 결정된 후에야 무대 위에 등장할 수 있다.

객체지향의 사실과 오해 p.129

필자가 객체지향 설계에서 가장 강조하는 것은 ‘협력‘과 ‘메시지‘다.
협력과 메시지가 객체지향 설계의 출발점이고 전체적인 설계의 방향을 결정한다.
협력과 메시지를 잘 설계하면 객체 공동체에서 각 객체들은 적절한 책임과 역할을 부여 받을 것이다.
이는 곧 이해하기 쉽고 단순하며, 변화에 유연한 체계를 만드는 길이다.

성공적인 소프트웨어들의 공통점은 훌륭한 기능을 제공함과 동시에 사용자가 원하는 새로운 기능을 빠르고 안정적으로 추가할 수 있는 구조를 가졌다는 점이다.
이러한 안정적인 구조 설계를 위해서는 ‘도메인 모델’을 기반으로 애플리케이션이 설계되어야 한다.
그 이유는 사용자가 도메인을 바라보는 관점이 소프트웨어에 그대로 반영될 수 있기 때문이다. 
이는 곧 사용자와 설계자, 그리고 소프트웨어가 모두 동일한 관점으로 바라보게 된다는 의미이므로, 소통에 유리할 것이며  향후 변화에 대한 대응을 효율적이고 빠르게 하는데 도움을 줄 것이다. 

소프트웨어 객체는 그 대상이 현실적인지, 현실적이지 않은지에 상관없이 도메인 모델을 통해 표현되는 도메인 객체들을 은유해야 한다. 이것이 도메인 모델이 중요한 이유다.
도메인 모델을 기반으로 설계하고 구현하는 것은 사용자가 도메인을 바라보는 관점을 그대로 코드에 반영할 수 있게 한다. 결과적으로 표현적 차이는 줄어들 것이며, 사용자의 멘탈 모델이 그대로 코드에 녹아 스며들게 될 것이다.

객체지향의 사실과 오해 p.189

객체 지향 소프트웨어는 ‘이상한 나라’ 처럼 상상속의 사회와 같다.
공동체의 각 객체 구성원들이 서로 유기적으로 협력하고, 적절히 공개하며, 자신만의 자율성을 유지하며 공동의 목표를 향하고 있다.
이러한 유기적인 협력을 통해 이 사회는 안정적이면서도 성장을 지속할 수 있다.
이는 가상의 객체 지향 소프트웨어 세계 뿐 아니라 결국 우리가 꿈꾸는 세상이 아니던가?

You may also like...