04 역할, 책임, 협력
협력
요청하고 응답하며 협력하는 사람들
협력은 한 사람이 다른 사람에게 도움을 요청할 때 시작된다.
요청을 받은 사람은 요청한 사람에게 필요한 지식이나 서비스를 제공하는 것으로 응답한다.
협력은 다수의 연쇄적인 요청과 응답의 흐름으로 구성된다.
이상한 나라의 앨리스에서 하트 잭에 대한 공판이 열리는 법정
누가 파이를 훔쳤지?
파이를 누가 훔쳤는지에 대한 재판이 열렸다. 왕이 하얀 토끼에게 첫 번째 목격자를 부르라고 명령하자 하얀 토끼는 모자 장수를 부른다. 이내 왕은 모자 장수에게 증언하라고 명령한다. 모자 장수는 '저는 보잘 것 없는 사람입니다'라며 얘기한다.
이 재판 속에서 객체는 왕, 하얀 토끼, 모자 장수가 있으며 이들은 요청과 응답으로 협력을 한다.
왕이 모자 장수에게 '증언하라'라고 요청을 보낸 건 모자 장수가 그 요청을 응답하는데 필요한 정보와 행동을 가지고 있기 때문이다.
즉, 어떤 대상에 대한 요청은 그 대상이 요청을 처리할 책임이 있음을 암시한다.
책임
"객체지향 개발에서 가장 중요한 능력은 책임을 능숙하게 소프트웨어 객체에 할당하는 것"
-크레이그 라만
중요한 건 책임을 어떻게 구현할지 고민하기 전에, 객체와 책임을 명확히 결정해야 한다는 것이다. 책임은 객체지향 설계의 품질을 결정하는 가장 중요한 요소이다.
책임의 분류
- 하는 것(doing)과 아는 것(knowing)
- 책임은 객체의 외부에 제공해 줄 수 있는 정보(아는 것)와 외부에 제공해줄 수 있는 서비스(하는 것)의 목록이다.
- 따라서 책임은 객체의 공용 인터페이스(public interface)를 구성한다.
책임과 메시지
- 객체가 다른 객체에게 주어진 책임을 수행하도록 요청을 보내는 것을 메시지 전송이라고 한다.
- 메시지는 협력할 때 다른 객체로 접근할 수 있는 유일한 방법이다.
- 왕은 '증언하라' 메시지를 모자 장수에게 전송하고 모자 장수는 '증언하라' 메시지를 수신한다.
- 책임을 결정한 다음, 다른 객체와 협력할 수 있는 메시지를 결정한다. 책임을 메시지로 변환할 때, 보통 하나의 책임은 여러 메시지로 분할된다.
- 객체지향 설계는 어떤 객체가 어떤 책임을 수행해야 하고 어떤 객체로부터 메시지를 수신할 것인지를 결정하는 것으로부터 시작된다.
역할
책임의 집합이 의미하는 것
- 책임의 집합은 어떤 역할을 가지고 있음을 의미한다.
- 재판이라는 협력에 참여하기 위해 모자 장수는 '증인'의 역할을, 왕은 '판사'의 역할을 수행하고 있다.
역할이 답이다
- 위의 예시에서 왕은 판사라는 역할, 모자 장수는 증인이라는 역할을 가졌다. 여기서 판사와 증인은 바뀔 수 있다.
- 역할을 이용해 협력을 추상화하면 판사, 증인의 역할을 수행할 수 있는 객체는 대체할 수 있다.
- 단, 역할을 대체하기 위해서 각 역할이 수신할 수 있는 메시지는 동일한 방식을 가져야 한다.
- 동일한 역할을 수행하는 객체들은 동일한 메시지를 수신할 수 있기 때문에 동일한 책임을 수행할 수 있다.
- 역할은 객체지향 설계의 단순성, 유연성, 재사용성을 뒷받침하는 핵심 개념이다.
객체는 역할에 주어진 책임 이외의 다른 책임을 수행할 수도 있다. 따라서 대부분 객체들의 관계에서 일반화/특수화 관계가 성립한다.
객체의 모양을 결정하는 협력
흔한 오류
객체는 시스템에 필요한 데이터를 저장하기 위해 존재한다. 이는 틀렸다. 객체가 존재하는 이유는 행위를 하며 협력하기 위해서다.
협력에 따라 흐르는 객체의 책임
협력에서 객체가 수행할 책임, 즉 행동을 결정한 후 행동을 수행하는데 필요한 데이터를 고민해야한다.
다음은 객체에게 책임을 할당하고, 구현하는 순서이다.
- 협력을 구성하는데 필요한 책임을 고안한다.
- ex)누군가는 재판을 진행해야 하고(판사), 누군가는 증인을 증인석으로 불러야 하고, 누군가는 증언(증인)해야 한다.
- 그 책임을 수행하는 데 필요한 객체를 선택하고, 책임을 객체에게 할당한다.
- ex) 판사는 왕, 증인을 증인석에 부르는 일은 하얀 토끼, 증인은 모자 장수가 한다.
- 외부에 제공하게 될 행동을 정의한다.
- ex) 판사는 증인에게 '증언하라'라고 한다.
- 행동이 결정됐으니 각 객체가 필요로 하는 데이터를 정의한다.
- 그 다음 구현 클래스를 개발한다.
핵심은 객체를 충분히 협력적으로, 자율적으로 만들는 것이다.
객체지향 설계 기법
역할, 책임, 협력의 관점에서 애플리케이션을 설계하는 유용한 세 가지 기법
- 책임-주도 설계
- 시스템의 책임을 객체에게 할당하고, 각 객체가 책임을 수행하는 중 필요한 협력자를 찾아 해당 협력자에게 책임을 할당하는 순차적인 방식으로 객체들의 협력 공동체를 구축한다.
- 시스템이 제공해야하는 기능인 시스템 책임을 파악한다.
- 시스템 책임을 더 작은 책임으로 분할한다.
- 분할된 책임을 수행할 수 있는 객체 또는 역할을 찾아 책임을 할당한다.
- 객체가 책임을 수행하는 중에 다른 객체의 도움이 필요한 경우 이를 책임질 객체 또는 역할을 찾는다.
- 해당 객체에게 책임을 할당하고 두 객체가 협력한다.
- 시스템의 책임을 객체에게 할당하고, 각 객체가 책임을 수행하는 중 필요한 협력자를 찾아 해당 협력자에게 책임을 할당하는 순차적인 방식으로 객체들의 협력 공동체를 구축한다.
- 디자인 패턴
- 테스트 주도 개발
- 테스트 주도 개발의 핵심은 테스트를 작성하는 것이 아니다.
- 테스트는 별도의 보너스 같은 것이며, 실제 목적은 구체적인 코드를 작성해나가면서 역할, 책임, 협력을 식별하고, 그것이 적합한지 피드백받는 것이다.
'스터디' 카테고리의 다른 글
[모던 자바 인 액션] 4장. Stream (0) | 2023.06.30 |
---|---|
[모던 자바 인 액션] 3장. 람다, 함수형 인터페이스, 메서드 참조 (0) | 2023.06.28 |
[모던 자바 인 액션] 1,2장. Java 8의 변화, 동작 파라미터화 (0) | 2023.06.23 |
[객체지향의 사실과 오해] 3. 타입과 추상화 (0) | 2023.06.16 |
[ 객체지향의 사실과 오해 ] 2. 객체의 구성 (상태, 행동, 식별자) (0) | 2023.06.09 |
댓글