역할, 책임, 협력

2023. 9. 30. 20:11북리뷰/오브젝트

728x90

객체지향의 본질은 협력하는 객체들의 공동체를 창조하는 것이다.

객체지향의 핵심은 적절한 객체를 찾고, 적절한 책임을 할당하는 과정에서 드러난다

 

# 협력

 

객체는 고립된 존재가 아닌 다른 객체와 협력하는 사회적인 존재이다.

객체들은 협력하여 시스템 기능이라는 큰 목표를 달성한다.

두 객체 사이 메시지 전송/수신 을 통해 커뮤니케이션하며 목표를 이룬다.

매시지를 수신한 객체는 스스로 메시지 처리할 방법을 선택하여 내부에 구현한 메서드를 실행해 요청에 응답한다. 

각 내부 구현은 외부에서 직접 접근을 못하게 캡슐화를 한다.

 

정리해보면, 객체가 자신이 할당된 책임을 수행하던 중에 외부의 도움이 필요하면 적절한 객체에게 메시지를 전송해서 협력을 요청한다.

이러한 협력이 연쇄되어 애플리케이션의 기능이 구현된다.

 

상태는 객체가 행동하는 데 필요한 정보에 의해 결정되고, 행동은 협력 안에서 객체가 처리한 메시지로 결정된다.

즉, 협력이 객체를 구성하는 행동과 상태를 모두 결정한다.

협력은 객체를 설계하는데 필요한 문맥(context)을 제공한다

 

# 책임

협력에 참여하기 위해 객체가 수행하는 행동을 책임이라고 부른다.

즉, 책임은 행위의 집합이며, 유지헤야하는 정보와 수행할 수 있는 행동에 대해 서술한 문장이다.

책임은 크게 '하는 것' 그리고 '아는 것' 두 범주로 나눈다.

 

### 하는 것

- 객체를 생성하거나, 계산을 수행하는 등 스스로 하는 것

- 다른 객체의 행동을 시작시키는 것

- 다른 객체의 활동을 제어하는 것

 

### 아는 것

- 사적인 정보에 관해 아는 것

- 관련 객체에 관해 아는 것

- 자신의 유도하거나 계산할 수 있는 것에 관해 아는 것

 

책임은 객체가 수행할 수 있는 행동을 종합적이고 간략하게 서술하기 때문에 메시지보다 추상적이고 개념적으로 더 크다.

 

# 책임 할당

자율적인 객체를 만드는 가상 기본적인 방법은 책임을 수행하는데 필요한 정보를 가장 잘 알고 있는 전문가에게 그 책임을 할당하는 것이다.

객체에게 책임을 할당하기 위해서는 먼저 협력이라는 문맥을 정의해야 한다.

시스템이 사용자에게 제공하는 기능을 시스템이 담당할 하나의 책임으로 바라보는 것 부터 시작한다. 

어떤 책임을 할당해야하는 지 생각하고, 그 책임에 맞는 메시지명을 정의한다

메시지를 선택했으면, 메시지를 처리할 적절한 객체를 선택한다.

해당 메시지에 관련한 정보를 가장 많이 알고 있는 객체에게 책임을 할당해야 한다. 

또한, 해당 책임을 수행하기 위해 다른 정보가 필요하면, 외부의 객체에게 요청해야 한다.

해당 요청에 맞는 메시지를 새롭게 명명하자

마지막으로, 새롭게 생성한 메시지를 수행할 객체를 선정하고, 해당 객체와 연결을 한다

이런 식으로 객체지향 설계는 협력에 필요한 메시지를 찾고, 메시지를 적절한 객체를 선택하는 반복적인 과정을 통해 이루어진다. 

메시지 자체가 퍼블릭 인터페이스를 구성한다는 점을 눈여겨보자.

 

물론, 어떤 경우에는 응집도와 결합도 관점에서 정보 전문가가 아닌 다른 객체에게 책임을 할당할 수도 있으나, 기본적인 전략은 책임을 수행할 정보 정문가를 찾는 것이 바람직하다.

 

# 책임 주도 설계

위와 같이 책임에 초점을 맞춰서 책임을 찾고, 해당 책임을 수행할 적절한 객체를 찾아 책임을 할당하는 방식을 책임 주도 설계라고 한다. 

책임 주도 설계 과정을 정리해보면 다음과 같다.

 

1. 시스템이 사용자에게 제공해야 하는 기능인 시스템 책임을 파악

2. 시스템 책임을 더 작은 책임으로 분할

3. 분할된 책임을 수행할 수 있는 적절한 객체 또는 역할을 찾아 책임을 할당

4. 객체가 책임을 수행하는 도중 다른 객체의 도움이 필요한 경우 이를 책임질 적절한 객체 또는 역할 탐색

5. 해당 객체 또는 역할에게 책임을 할당하면서 두 객체가 협력

 

협력은 객체를 설계하기 위한 구체적인 문맥을 제공한다.

그리고, 책임 주도 설계는 자연스럽게 객체의 구현이 아닌 책임에 집중할 수 있다.

또한, 메시지가 객체를 결정하고, 행동이 상태를 결정한다는 것이 특징이다.

 

## 메시지와 객체

객체에 책임을 할당하는 데 메시지를 먼저 식별하고, 메시지를 처리할 객체를 나중에 선택하는 것이 중요하다.

이렇게하면 장점은 다음과 같다.

1. 객체가 최소한의 인터페이스를 가질 수 있게 된다.

2. 객체는 충분히 추상적인 인터페이스를 가진다.

즉, 무엇(what)이 하는지는 표현하지만, 어떻게(how)를 수행하는지를 노출해서는 안 된다.

 

## 행동과 상태

객체는 협력하기 위해 존재한다.

즉, 객체는 협력에 필요한 행동을 제공해야 한다.

즉, 협력에 적합한지를 결정하는 것은 객체의 상태가 아니라 행동이다.

상태는 단지 객체가 행동을 수행하기 위해 필요한 재료일 뿐이다.

 

# 역할

역할을 인터페이스 혹은 추상 클래스로 보면 이해가 쉽다.

객체가 어떤 특정한 협력 안에서 수행하는 책임의 집합을 역할이라 한다.

실체로 협력을 모델링 할때는 어떠한 객체가 아닌 역할에 책임을 할당한다고 보는 것이 맞다.

책임 할당 과정을 자세히 보면, 역할이 무엇인지 찾은 다음, 역할을 수행할 객체를 선택하는 것이 맞다.

역할은 다른 것으로 교체할 수 있는 책임의 집합이다.

역할을 통해 유연하고 재사용 가능한 협력을 얻을 수 있다.

역할은 추상화다.

역할을 통해서 불필요한 중복 코드를 제거할 수 있다.

그럼 오직 한 중류의 객체만 협력에 참여하는 상황에서도 역할을 고려해서 설계해야 할까?

레베가의 말에 따르면 역할을 단지 한 종류의 객체만 협력에 참여할 필요가 있다면 해당 후보는 객체가 된다고 한다.

즉, 협력에 접합한 책임을 수행하는 대상이 한 종류라면 간단하게 객체로 간주한다.

 

역할과 객체를 언제 분리해야 하는지 고민된다면, 처음에 단순하게 객체로 시작하고, 반복적으로 책임과 협력을 정제해가면서 필요한 순간에 객체로부터 역할을 분리해내는 것이 좋은 방법이다.

 

 

 

## 추상 클래스 & 인터페이스

상태와 행동의 기본 구현이 필요하면 추상클래스,

공통의 구현 필요가 없이 단지 책임의 목록만 정의하면 인터페이스가 적합하다.

 

## 배우와 배역

연극에서 배우들은 배역을 맡아 연기를 한다.

연극의 배우와 배역은 다음과 같은 특징이 있다.

 

- 배역은 배우가 연기하는 역할이다

- 연극이 끝나면 배우는 배역을 벗는다.

- 서로 다른 배우들이 동일한 배역을 연기한다.

- 하나의 배우가 여러 배역을 연기할 수 있다.

 

배역을 역할, 배우를 객체로 바꿔서 봐도 마찬가지이다.

즉, 역할은 특정 협력에 참여해서 책임을 수행하는 객체의 일부이고,

역할은 객체가 협력에 참여하는 잠시동안만 존재하는 일시적 개념이고,

오직 시스템 문맥 안에서 무엇을 하는지에 의해서만 정의된다.

역할은 객체의 페르소나이다. 

 

동일 역할을 여러 객체가 대체 가능하고,

한 객체는 다양한 역할을 가질 수 있다.

또한 특정 협력 안에서는 일시적으로 하나의 역할만 보여진다.

 

728x90

'북리뷰 > 오브젝트' 카테고리의 다른 글

설계 품질과 트레이드오프  (0) 2023.10.01
객체지향 프로그래밍  (0) 2023.09.30
객체, 설계  (0) 2023.09.29