협력하는 객체들의 공동체
객체지향이라는 예술은 적절한 객체에게 적절한 책임을 할당하는 것에서 시작된다.
객체지향 설계를 하기 전, 객체의 역할을 확립하자. 객체의 역할은 아래와 같은 특징을 가진다.
- 여러 객체가 동일한 역할을 수행할 수 있다.
- 하나의 객체가 여러 역할을 수행할 수 있다.
- 역할은 대체 가능성을 의미한다.
- 객체는 책임을 다하는 방법을 선택할 수 있다.
협력하는 객체의 덕목
- 다른 객체의 요청한 것 (what)에 협력적으로 응답한다.
- 객체가 어떻게 (how) 응답하는 지에 대해 충분히 자율적이다.
객체는 자율적이기 위해서 어떤 행동(behavior)을 하기 위해 필요한 상태(state)를 알고 있어야 한다.
예를 들어, 바리스타는 커피 제조를 위한 방법을 기억하는 상태에 있고, 그렇기 때문에 이를 달성하는 방법을 스스로 결정할 수 있는 자율적인 존재가 된다.
협력과 메시지, 메서드
송신자 객체는 수신자 객체에게 협력을 위한 메시지를 전송한다.
수신자는 메시지를 받고 자신의 방법대로 메시지를 처리하는데, 이 방법을 메서드라고 한다.
메서드는 클래스 안에 포함된 함수나 프로시저를 통해 구현된다. 즉, 메서드는 머리 위에 둥둥 떠오르는 추상적인 로직이고, 이를 구현하기 위해 함수나 프로시저를 ‘사용’하는 것이다.
특히, 수신자가 런타임 시점에 메서드를 선택할 수 있다는 것이 객체지향의 핵심이다. 절차지향에서는 컴파일 시점에서 실행 코드가 결정된다.
캡슐화의 개념은 메시지와 메서드를 분리하는 것에서 출발한다.
중요한 건 클래스가 아니다
클래스는 구성 요소일 뿐이지, 클래스가 없이도 객체지향 프로그래밍을 수행하는 언어가 있다. 메시지를 주고받는 객체의 관점으로 사고를 바꾸자. 클래스는 정적이고, 메시지를 주고받는 객체는 동적이다.
이상한 나라의 객체
객체지향은 사물을 하나의 독립된 객체로 보는 인간의 기본적인 인지 능력에 기반한 개념이다. 객체지향 패러다임은 현실 세계를 기반으로 새로운 세계를 창조한다.
상태와 행동
객체의 상태를 결정하는 것은 행동이다. 즉 행동의 결과는 ‘상태’라는 형태로 나타난다.
상태는 행동의 과정과 결과를 단순하게 기술하기 위해 고안된 개념이다.
객체로 삼을 수 있는 물리적 / 개념적 사물의 특징은 아래와 같다.
- 개수를 셀 수 있다.
- 다른 사물과 구분할 수 있다.
- 생성 시점을 알 수 있다.
- 독립적인 하나의 단위로 인식할 수 있다.
객체는 행동, 상태, 식별자를 지닌 실체라고 표현한다.
프로퍼티
객체의 상태나 특성을 표현하기 위한 개념들은 하나의 값으로서 프로퍼티로 분류된다. 프로퍼티는 고정이고, 프로퍼티 값은 시간의 흐름에 따라 바뀌는 동적 개념이다.
한 객체의 프로퍼티로서 다른 객체가 사용될 수 있는데, 이렇게 객체 간의 의미 있는 연결을 링크라고 한다. 링크와 달리 객체를 구성하는 단순한 값은 속성(attribute)이다.
링크 관계에 있는 객체는 서로의 객체를 직접 변경할 수 없다.
그렇다면 객체가 자발적으로 행동하도록 만들어야 한다. 객체의 행동에 의해 변하는 상태들은 부수 효과 (side effect) 이다.
예를 들어, 앨리스가 음료를 마신다면 음료의 양은 줄어든다. 앨리스 객체는 음료를 마셨다는 메시지를 음료 객체에게 전달할 뿐, 직접 음료의 양을 줄일 수 없다.
정리하면,
객체의 행동은 상태에 영향을 받는다. 예를 들어, 앨리스는 키가 100cm 이하여야 문을 지나가는 행동을 할 수 있다.
객체의 행동은 상태를 변경한다. 예를 들어, 음료를 마시면 앨리스의 키는 50cm 증가한다.
상태 캡슐화
서로 다른 객체의 협력 관계에서, 객체는 다른 객체에게 행동을 노출할 뿐 상태 변경에 대해서는 전혀 알지 못한다. 이를 상태 캡슐화 라고 한다.
앨리스가 음료를 마신다면 음료의 양은 줄어든다. 앨리스 객체는 음료를 마셨다는 메시지를 음료 객체에게 전달할 뿐, 직접 음료의 양을 줄일 수 없다.
위에서 설명한 이 이야기가 상태 캡슐화에 해당된다. 객체의 자율성이 높아지고 협력은 단순하고 유연해진다.
식별자
객체는 식별 가능하므로 모두 고유한 식별자를 가지고 있다.
값은 숫자, 문자열, 날짜와 같이 변하지 않는 양을 모델링하며 값의 ‘상태’는 변하지 않기에 불변 상태 (immutable state) 를 가진다고 표현한다.
값의 상태란 메모리 상의 인스턴스 변수가 담고 있는 값을 의미한다. ==
연산자 등을 사용해 객체의 동등성(equality)을 판단할 수 있다. 상태로 동등성을 판단할 수 있기 때문에 값은 식별자가 필요 없다.
⇒ String
, Integer
등의 클래스로 만들어진 객체를 값 객체 (value object)라고 한다.
반면 객체는 가변 상태(mutable state) 로, 상태가 같더라도 독립적인 별개의 객체이다.
따라서 객체는 식별자를 가지고 있고, 식별자를 기반으로 객체가 같음을 판단하는 성질을 동일성 (identical) 이라고 한다. 상태가 다르더라도 식별자가 같으면 같은 객체이며, 이를 통해 가변 상태인 객체도 같음을 판단할 수 있다.
⇒ Person
과 같이 식별자를 가지는 객체를 참조 객체 (reference object) / 엔티티 (entity)라고 한다.
행동이 우선이다.
객체를 설계할 때 객체가 어떤 행동을 하는 지 먼저 결정해야 한다. 행동에 초점을 두어 생각하는 이유는 다음과 같다.
- 객체의 캡슐화
- 다른 객체와의 협력으로 인한 재사용성
- 협력의 문맥에 맞는 행동을 하는 객체를 설계해야 한다. 따라서 적합한 객체는 적절한 행동을 하는 객체인 것이다.
정리하면,
- 애플리케이션에 필요한 협력을 생각
- 협력 관계에 놓인 객체를 생각
- 각 객체가 수행할 행동을 생각
- 행동에 필요한 정보를 생각하여 상태를 결정
이러한 책임 주도 설계(Responsibility-Driven Design, RDD)의 목적은 응집도가 높고 재사용 가능한 객체를 설계하는 것이다.
현실 세계와의 비교
소프트웨어 세계의 객체는 현실 세계의 것과 달리 능동적이다. 사물임에도 불구하고 실제 생명체인 것처럼 스스로 행동한다. 이를 의인화라고 부른다.
소프트웨어는 현실 세계의 사물들을 은유로서 이해하고 있다. 즉 완전히 동일한 사물을 지칭하지는 않지만 현실 속 객체의 의미를 소프트웨어로 전달함으로써 이해하기 쉽게 묘사하는 것이다.
'DEV book > 객체지향의 사실과 오해' 카테고리의 다른 글
[OOP] 객체지향의 사실과 오해 5, 6장 - 자율적인 객체와 도메인 모델링 (1) | 2024.02.06 |
---|---|
[OOP] 객체지향의 사실과 오해 3, 4장 리뷰 - 역할, 책임, 협력 (0) | 2024.02.02 |