- Published on
2024.01.01
객체지향의 사실과 오해 - 01. 협력하는 객체들의 공동체
객체지향의 목표는 실세계를 모방하는 것이 아니다.
객체지향을 배우게 되면 처음 마주하는 설명은 '객체지향은 현실 세계의 실체가 있는 사물에 대한 추상화' 등으로 듣게 된다. 이는 직관적으로 이해하기 힘든 설명이며, 철학적인 접근이면 몰라도 실용적인 관점에서는 적합한 설명이 아니라고 한다. 실세계의 모방이라는 개념이 비현실적이지만 여전히 이러한 접근이 사용되는데, 이는 실세계에 대한 비유가 객체지향의 다양한 측면을 이해하고 학습하는 데 효과적이기 때문이다.
현실 세계의 물체와 개념에 비추어 비유하는 것을 보면 스스로 생각하고 결정하는 생명체에 비유하는 것은 상태와 행위를 캡슐화
하는 객체의 자율성
을 설명하는 데 효과적이다. 현실의 암묵적인 약속과 명시적인 계약을 통한 협력은, 메시지를 통해 협력
하는 객체들의 관계를 설명할 수 있다. 실제 사물을 통해 객체를 식별하고 구현하는 개념은 객체지향 설계의 핵심 사상인 연결완전성
을 설명할 수 있다. 이처럼 실세계의 모방이라는 개념은 객체지향이라는 개념을 학습하는 데는 효과적이다.
협력하는 사람들
카페에서 커피를 주문하고 제조하는 과정을 통해 역할
, 책임
, 협력
의 세 가지 개념의 적용을 살펴볼 수 있다. 커피를 주문하고, 제조하고, 커피를 받는 과정 사이에는 암묵적인 협력
관계가 존재한다. 협력
하는 과정에서 각각의 역할
이 있기 때문이다. 손님은 커피를 주문하는 책임
을, 캐셔는 손님의 주문을 받는 책임
을, 바리스타는 커피를 제조하는 책임
을 수행한다. 현실 세계에서 역할
, 책임
, 협력
은 우리가 다른 사람과 접촉하는 모든 곳에 존재한다. 이 세 가지가 객체지향에서 가장 중요한 개념이다.
요청과 응답으로 구성된 협력
사람들은 문제를 해결하기 위해 도움을 요청한다. 하나의 문제를 해결하기 위해 다수의 역할이 필요하기 때문에 한 사람에 대한 요청은 또 다른 사람에게 요청을 유발하며, 요청은 연쇄적으로 발생하게 된다. 커피를 예로 협력
의 과정을 살펴보면 손님의 커피 요청
은, 캐셔의 커피 제조 요청
으로 바리스타에게 전달된다. 그리고 요청을 받은 사람은 요청에 대해 응답
하는데, 요청과 마찬가지로 응답 역시 요청의 반대 방향으로 연쇄적으로 전달된다. 요청
과 응답
을 통한 협력
은 더 거대하고 복잡한 문제를 해결할 수 있도록 만들어준다.
역할과 책임
이렇게 협력하는 과정에서 각각은 역할
을 부여받는다. 협력의 과정에서 그 사람이 갖는 책임
을 의미한다. 각각의 역할
은 역할에 맞는 책임
이 있다. 특정한 역할은 특정한 책임을 암시하며, 협력에 참여하면서 역할에 맞는 책임을 수행한다. 이렇게 역할
과 책임
은 협력
에 필요한 핵심 구성 요소이다.
여기서, 협력을 위해 역할을 맡고 책임을 수행하는 사실에 중요한 개념들이 있다.
여러 사람이 동일한 역할을 수행할 수 있다
주문한 음식을 제대로 받을 수 있다면 주문을 누가 받는지는 중요하지 않다. 마찬가지로 요청한 음식을 제대로 만들 수 있다면 누가 만드는지는 중요하지 않다. 역할을 수행할 사람이 그만두면 다른 사람으로 역할을 수행할 수 있다.역할은 대체 가능성을 의미한다
손님 입장에서 캐셔는 대체 가능하다. 두 명의 캐셔가 있다면 누가 주문을 받더라도 문제가 되지 않는다.책임을 수행하는 방법은 자율적으로 선택할 수 있다
동일한 요청에 대해 요청을 처리하는 방법은 자유롭게 선택할 수 있다. 같은 요청도 바리스타는 각각의 방식으로 처리할 수 있다. 이 같이 동일한 요청을 서로 다른 방식으로 응답할 수 있는 능력을다형성
이라 한다.한 사람이 동시에 여러 역할을 수행할 수 있다
캐셔와 바리스타는 역할이 나누어져 있지만, 혼자서 두 가지 역할을 모두 수행하는 것도 가능하다.
역할, 책임, 협력
어떤 객체도 섬이 아니다.
이러한 현실 세계의 비유를 옮겨 오면 객체지향을 설명할 수 있다. 사람을 객체
로, 요청을 메시지
로, 요청을 처리하는 방법을 메서드
로 바꾸는 것이다.
객체의 세계는 인간 세계와 비슷한데, 객체도 마찬가지로 객체에 주어진 역할과 책임을 다하며, 객체의 목적을 위해 다른 객체와 협력한다. 애플리케이션은 작은 책임으로 분할되고, 이러한 책임은 객체에 의해 수행된다. 다중에 다른 객체에 도움을 요청하며, 연쇄적인 요청과 응답의 흐름으로 구성된 협력이 구현된다. 결국 시스템은 역할과 책임을 수행하는 객체로 분할된다. 객체지향 설계는 적절한 객체에 적절한 책임을 할당하는 것에서 시작되며, 책임은 객체지향 설계의 품질을 결정하는 가장 중요한 요소다.
협력 속에 사는 객체
객체지향 애플리케이션의 주체는 객체
다. 객체지향을 객체지향이라고 부르는 이유는 객체가 중심이기 때문이다. 객체가 없으면 역할, 책임, 협력이 의미가 없다. 작은 기능도 객체 혼자 담당하기에는 복잡하고 거대하므로, 객체는 다른 객체와의 협력을 통해 기능을 구현한다. 협력을 이루기 위해 객체는 두 가지가 필요하다.
객체는 충분히
협력적
이어야 한다.
혼자 모든 것을 하려는 객체는 내부적인 복잡도로 자멸한다. 충분히 협력적이라는 말은 다른 객체의 명령대로 행동하는 수동적인 것을 의미하는 것이 아니다. 객체는 명령을 듣는 것이 아니라, 요청에 응답하는 것이다. 어떻게 응답할지는 객체 스스로 판단하고 결정하며, 응답 여부도 스스로 결정할 수 있다.객체는 충분히
자율적
이어야 한다.
객체들은 공동의 목표를 위해 협력하지만, 스스로의 결정에 따라 행동하는 자율적인 존재다. 충분히 개방적이면서 충분히 자율적인 객체들의 공동체를 설계하는 것이 중요하다.
상태와 행동을 함께 지닌 자율적인 객체
객체는 상태
와 행동
을 함께 지닌 실체라고 정의되는데, 이는 객체가 협력하기 위해 어떤 행동을 한다면, 그 행동을 하는 데 필요한 상태를 지니고 있어야 함을 의미한다. 객체가 자율적으로 되기 위해서는 필요한 행동과 상태를 함께 지니고 있어야 한다.
객체의 자율성을 위해 객체의 내부와 외부를 명확하게 구분해야 한다. 객체의 내부는 외부에서 간섭할 수 없도록 하고, 접근이 허락된 수단을 통해서만 의사소통할 수 있어야 한다. 객체는 다른 객체가 무엇을 수행하는지는 알 수 있지만 어떻게 하는지는 알 수 없다.
과거에는 데이터와 프로세스를 엄격히 구분했지만, 객체지향에서는 데이터와 프로세스를 객체라는 틀 안에 묶어 놓아 객체의 자율성을 보장한다. 이것이 전통적인 개발 방법과 객체지향을 구분 짓는 핵심 차이다. 자율적인 객체는 유지보수가 쉽고 재사용이 용이한 시스템을 구축할 수 있도록 한다.
협력과 메시지 / 메서드와 자율성
객체지향의 의사소통 수단은 메시지
이다. 한 객체는 다른 객체에 요청을 전송하고, 다른 객체는 요청을 수신한다. 이렇게 객체지향의 협력은 송신자와 수신자의 관계로 이루어져있다.
객체가 수신된 메시지를 처리하는 방법을 메서드
라 한다. 메시지에 따라 특정 메서드가 실행되는데, 외부의 요청인 메시지와 요청을 처리하기 위한 메서드를 분리하는 것은 객체의 자율성을 높이는 핵심 메커니즘이다. 이는 캡슐화
와도 밀접하게 연관되어 있다.
객체지향의 본질
지금까지의 내용을 정리하면, 객체지향이란 자율적인 객체들의 공동체이다. 자율적인 객체란 상태와 행위를 지닌 객체를 의미하며 객체는 다른 객체와 협력한다. 각각의 객체는 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다. 객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하기 위한 특정 메서드를 자율적으로 선택한다.
많은 사람들이 객체지향을 얘기하면 클래스
를 먼저 떠올린다. 하지만 이는 본질에서 먼 접근으로, 클래스가 객체지향에서 중요한 요소이긴 하지만, 객체지향의 핵심은 아니다. 자바스크립트 같은 프로토타입 기반의 객체지향 언어에는 클래스가 존재하지 않고 오직 객체만이 존재한다. 클래스를 강조하는 관점은 객체의 캡슐화를 저해하고 클래스를 강하게 결합해 유연하고 확장 가능한 애플리케이션 구축을 방해한다.
객체지향 설계를 위해서는 클래스의 관점을 객체의 관점으로 바꾸어야 한다. 클래스의 구조와 메서드가 아닌 객체의 역할, 책임, 협력에 집중해야 한다.
객체지향에 대한 뚜렷한 시야 없이 나도 어렴풋하게 객체지향에서는 클래스를 다루는 것으로 생각했었다. 책의 첫 장을 가지고 객체지향을 이해할 순 없지만, 계속해서 책임, 역할, 협력 등의 핵심 개념을 반복 설명하는 것과 현실 세계와의 비유를 통해 객체지향이 말하고 싶어 하는 바는 조금 다가왔다. 최근 강의를 듣거나 아티클을 보면서 객체지향에 대한 관심이 생겼는데, 객체지향에 대한 잘못된 지식이 자리 잡기 전에 좋은 책을 만난 것 같다. 특히나 책이 특정 언어나 코드를 예시로 들면서 설명하는 형식이 아니라, 객체지향의 본질에 대한 접근으로 시작해서 좋은 것 같다.