오브젝트 3장 - 역할, 책임, 협력

변은서·2022년 12월 18일
0

오브젝트

목록 보기
3/3

객체지향 패러다임의 관점에서 핵심은 역할, 책임, 협력이다. 역할, 책임, 협력이 제자리를 찾지 못한 상태라면 응집도 높은 클래스와 중복 없는 상속 계층을 구현한다고 하더라도 애플리케이션이 침몰하는 것을 구원하지 못할 것이다.

협력

영화 예매 시스템 돌아보기

다양한 객체들이 영화 예매라는 기능을 구현하기 위해 메시지를 주고받아 상호작용한다. 이처럼 객체들이 애플리케이션의 기능을 구현하기 위해 수행하는 상호작용을 협력이라고 한다. 객체가 협력에 참여하기 위해 수행하는 로직은 책임이라고 부른다. 객체들이 협력 안에서 수행하는 책임들이 모여 객체가 수행하는 역할을 구성한다.

협력

메시지 전송은 객체 사이의 협력을 위해 사용할 수 있는 유일한 커뮤니케이션 수단이다. 메시지를 수신한 객체는 메서드를 실행해 요청에 응답한다. 객체가 메시지를 처리할 방법을 스스로 선택한다는 점이 중요하다. 외부 객체는 메시지만 전송할 수 있을 뿐이며 어떻게 처리할지는 메시지를 수신한 객체가 직접 결정한다.

협력이 설계를 위한 문맥을 결정한다.

객체가 가질 수 있는 상태와 행동을 어떤 기준으로 결정해야 할까? 객체를 설계할 때 어떤 행동과 상태를 할당했다면 그 이유는 무엇인가? 객체의 행동을 결정하는 것은 객체가 참여하고 있는 협력이다. 협력이 바뀌면 객체가 제공해야 하는 행동 역시 바뀌어야 한다. 객체의 상태를 결정하는 것은 행동이다. 객체의 상태는 그 객체가 행동을 수행하는 데 필요한 정보가 무엇인지로 결정된다. 상태틑 객체가 행동하는 데 필요한 정보에 의해 결정되고 행동은 협력 안에서 객체가 처리할 메세지로 결정된다. 결과적으로 객체가 참여하는 협력이 객체를 구성하는 행동과 상태 모두를 결정한다. 따라서 협력은 객체를 설계하는 데 필여한 일종의 문맥을 제공한다.

책임

책임이란 무엇인가

협력에 참여하기 위해 객체가 수행하는 행동을 책임이라 부른다. 객체에 의해 정의되는 응집도 있는 행위의 집합으로 객체가 유지해야 하는 정보와 수행할 수 있는 행동에 대해 개략적으로 서술한 문장이다. 즉, 객체의 책임은 '무엇을 알고 있는가' 와 '무엇을 할 수 있는가'로 구성된다. 일반적으로 책임과 메시지의 크기는 다르다. 처음에는 단순한 책임이라고 생각했던 것이 여러 개의 메시지로 분할되기도 하고 하나의 객체가 수행할 수 있다로 생각했던 책임이 나중에는 여러 객체들이 협력해야만 하는 커다란 책임으로 자라는 것이 일반적이다. 어떤 책임을 수행하기 위해 필요한 정보를 알아야 할 책임도 있어야 한다. 적절한 협력이 적절한 책임을 제공하고 적절한 책임을 적절한 객체에게 할당해야만 단순하고 유연한 설계를 창조할 수 있다.

객체지향 설계에서 가장 중요한 것은 책임이다 객체에게 얼마나 적절한 책임을 할당하느냐가 설계의 전체적인 품질을 결정한다.

책임 할당

책임을 수행하는 데 필요한 정보를 가장 잘 알고 있는 전문가에게 그 책임을 할당하는 것을 Information expert pattern이라고 부른다.

책임 주도 설계

책임을 찾고 책임을 수행할 적절한 객체를 찾아 책임을 할당하는 방식으로 협력을 설계하는 방법을 책임 주도 설계(Responsibility-Driven Design, RDD) 라고 부른다. 책임주도설계는 자연스럽게 객체의 구현이 아닌 책임에 집중할 수 있게 한다.

메시지가 객체를 결정한다

객체가 최소한의 인터페이스를 가질 수 있게 된다. 필요한 메시지가 식별될 때까지 객체의 퍼블릭 인스턴스에 어떤 것도 추가하지 않는다. 때문에 적절한 크기의 인터페이스를 가질 수 있다.
객체는 충분히 추상적인 인터페이스를 가질 수 있게 된다. 객체의 인터페이스는 무엇을 하는지는 표현하지만 어떻게 수행하는지를 노출해서는 안된다. 메시지는 외부 객체가 요청하는 무언가를 의미하기 때문에 메시지를 먼저 식별하면 무엇을 수행할지에 초점을 맞추는 인터페이스를 얻을 수 있다.

행동이 상태를 결정한다

객체가 협력에 필요한 행동을 제공해야 한다. 객체의 행동이 아니라 상태에 초점을 맞추면 안된다. 객체의 내부 구현에 초점을 맞춘 설계 방법을 데이터-주도 설계(Data-Driven Disign) 라고 부른다. 캡슐화를 위반하지 않도록 구현에 대한 결정을 뒤로 미루면서 갹체의 행위를 고려하기 위해 협력이라는 문맥 안에서 객체를 생각해야 한다. 행동이 중요하다.

역할

역할과 협력

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

유연하고 재사용 가능한 협력

역할이 중요한 이유는 역할을 통해 유연하고 재사용 가능한 협력을 얻을 수 있기 때문이다. 동일한 책임을 수행하는 역할을 기반으로 두 개의 협력을 하나로 통합할 수 있다. 따라서 역할을 이용하면 불필요한 중복 코드를 제거할 수 있다.
역할을 구현하는 가장 일반적인 방법은 추상 클래스와 인터페이스를 사용하는 것이다.

객체 대 역할

역할은 객체기 참여할 수 있는 일종의 슬롯이다. 한 종류의 객체만 협력에 참여하는 상황에서 역할이라는 개념을 고려하는 것이 유용할까? 이때 후보는 객체가 된다.
협력 -> 역할 -> 객체 -> 클래스
협력은 역할들의 상호작용으로 구성되고 협력을 구성하기 위해 역할에 적합한 객체가 선택되며 객체는 클래스를 이용해 구현되고 생성된다. 어떤 것이 역할이고 어떤 것이 객체인지가 또렷하게 드러나지는 않을 것이다. 특히나 명확한 기준을 세우기 어렵고 정보가 부족한 설계 초반에는 결정을 내리기가 더욱 어려울 것이다. 설계 초반에는 적적한 책임과 협력의 큰 그림을 탐색하는 것이 가장 중요한 목표여야 하고 역할과 객체를 명확하게 구분하는 것은 그렇게 중요하지 않다. 역할 모델링개념은 역할을 설계의 중심 개념으로 본다. 이는 UML에 큰 영향을 미치기도 했고 최근 중요한 구성 요소로 간주하기 시작했다.

역할과 추상화

추상화의 첫 번째 장점은 세부 사항에 억눌리지 않고도 상위 수준의 정책을 쉽고 간단하게 표현할 수 있다는 것이다. 협력이라는 관점에서는 세부적인 사항을 무시하고 추상화에 집중하는 것이 유용하다.
추상화의 두 번째 장점은 설계를 유연하게 만들 수 있다는 것이다. 역할이라는 추상화를 이용하면 기존 코드를 수정하지 않고도 새로운 행동을 추가할 수 있다. 결과적으로 앞으로 추가될 미지의 할인 정책과 할인 조건을 수용할 수 있는 유용한 설계를 얻을 수 있다. 프레임워크나 디자인 패턴과 같이 재사용 가능한 코드나 설계 아이디어를 구성하는 핵심적인 요소가 바로 역할이다.

배우와 배역

연극 안에서 배역을 연기하는 배우라는 은유는 협력 안에서 역할을 수행하는 객체라는 관점이 가진 입체적인 측면들을 훌륭하게 담아낸다. 협력은 연극, 코드는 극본이다. 배우는 연극이 상영될 때 배역이라는 특정한 역할을 연기한다. 객체는 협력이라는 실행 문맥 안에서 특정한 역할을 수행한다. 배우는 연극이 끝나면 자신의 배역을 잊고 원래의 자기 자신을 되찾는다. 협력이 끝나고 원래의 객체로 돌아올 수 있다. 협력이라는 문맥 안에서 역할은 특정한 협력에 참여해서 책임을 수행하는 객체의 일부다. 일시적인 개념이며 모양, 구조에 의해 정의될 수 없다. 역할은 객체의 페르소나다. 객체는 다양한 역할을 가질 수 있다. 객체는 협력에 참여할 때 협력 안에서 하나의 역할로 보여진다. 다른 협력에 참여할 때는 다른 역할로 보여진다. 협력의 관점에서 동일한 역할을 수행하는 객체들은 서로 대체 가능한다. 역할은 특정한 객체의 종류를 캡슐화하기 때문에 동일한 역할을 수행하고 계약을 준수하는 대체 가능한 객체들은 다형적이다.

profile
은또

0개의 댓글