오브젝트


앞선 챕터에서 객체지향 프로그래밍을 구성하는 다양한 요소와 구현 기법을 살펴보았다. 클래스 / 추상 클래스 / 인터페이스 를 조합하여 객체지향 프로그램을 구조화 하는 기본적인 방법과 상속을 이용해 다형성 을 구현하는 기법을 소개하였다.

다형성동적 바인딩 이라는 메커니즘을 통해 구현된다는 사실도 살펴보았다.

또한 코드 재사용 측면에서 상속 보다는 합성캡슐화 의 측면에서 더 좋은 방법이라는 사실을 이해했다. 상속 을 이용하면 자식 클래스가 부모 클래스의 세부 구현 내용을 알아야 하지만 합성 을 이용하면 합성 객체의 인터페이스 에만 의존하고 내부 구현에는 신경 쓰지 않아도 되기 때문에 캡슐화 가 더 짙어진다.

이와 같은 내용은 객체지향 프로그래밍의 구현 의 측면에서 중요한 것들이지만 보다 객체지향 패러다임의 본질 에 맞추어 보자.

챕터 3. 역할, 책임, 협력

역할, 책임, 협력

객체지향의 본질은 협력하는 객체들의 공동체를 창조 하는 것이다. 객체지향 설계의 핵심은 협력을 구성하기 위해 적절한 객체를 찾고 적절한 책임을 할당하는 과정에서 드러난다.

클래스와 상속은 객체들의 책임과 협력이 어느 정도 자리를 잡은 후에 사용할 수 있는 구현 메커니즘일 뿐이다.

애플리케이션의 기능을 구현하기 위해 어떤 협력이 필요하고 협력을 위해 어떤 책임과 역할이 필요한지 고민하지 않은 채 너무 이른 시기에 구현에 초점을 맞추는 것은 변경하기 어렵고 유연하지 못한 코드를 낳는 원인이 된다.

다시한번 강조하지만 객체지향에서 가장 중요한 것은 역할, 책임, 협력 이다.


협력

객체지향 설계에 있어서 가장 먼저 고려해야 할 점은 협력 이다. 하나의 객체에서 모든 프로세스를 수행하는 것을 협력이라고 하지 않는다. 객체들의 협력이란 단어 뜻 그대로 객체들이 서로 상호작용 함으로써 목적(기능)을 달성하는 것이다.

여기서 얘기하는 상호작용이란 객체들이 관계를 맺으며 제어의 흐름이 적절하게 분배된 것을 의미한다.

각 객체가 협력에 참여하기 위해 수행하는 로직을 책임 이라 한다. 그리고 객체들이 협력 안에서 수행하는 책임들이 모여 역할 을 구성한다.

객체지향 시스템은 자율적인 객체들의 공동체 이다. 객체는 고립된 존재가 아니라 시스템의 기능이라는 더 큰 목표를 달성하기 위해 다른 객체와 협력하는 사회적인 존재이다. 그리고 협력 은 객체지향 세계에서 기능을 구현할 수 있는 유일한 방법 이다.

두 객체 사이의 협력 은 하나의 객체가 다른 객체에게 도움을 요청 할 때 시작된다. 메시지 전송 은 객체가 객체에게 도움을 요청 할 수 있는 유일한 커뮤니케이션 수단이다. 다시말해 지금까지 계속 강조해오던 객체들의 협력이란 객체들 사이에 메시지 전송 과 응답을 통해 이루어지는 상호작용이다.

메시지 전송 이 왜 협력 의 유일한 수단일까? 조금만 고민해보자. 객체지향 세계에서 객체들은 자율적으로 판단하고 행동하는 존재 라고 하였다. 이 말은 직접 객체의 내부를 들여다보고 하나하나 지시하는게 아니라 단순히 외부에서 필요한 것을 요청하면 객체가 스스로 판단하고 해석한 대로 행동함을 의미한다. 좀 더 프로그래밍 적으로 얘기하자면 외부에서는 인터페이스 를 통해 요청을 하고 객체는 자신만의 방법인 메서드 를 수행함으로써 요청에 응답한다.

다시말해 메시지 전송이 협력의 유일한 수단 이라는 말이 내포하는 것은 객체는 자신의 일을 스스로 수행하는 자율적인 존재 라는 것을 의미한다.

위와 같이 객체가 자율적인 존재가 되기 위해서는 자신의 상태를 직접 관리하고 스스로의 결정에 따라 행동 하게끔 설계를 해야한다. 즉, 필요한 정보와 정보에 기반한 행동을 같은 객체 안에 모아놓아야 한다. 이 말은 스스로 자신의 데이터에 대한 처리를 한다. 라는 의미와 같다.

여기서 의미하는 필요한 정보란 객체가 책임을 수행하기 위해 필요한 [데이터성 정보]와 직접 처리할 수 없는 일을 [위임(요청)할 객체]를 의미한다. 또한 정보에 기반한 행동이란 [데이터성 정보를 이용하여 스스로 처리하는 행동]과 [요청할 객체에게 메시지를 보내는 행동] 모두를 의미한다. 다른 객체에게 메시지를 보내는 행동 역시 책임을 수행하던 중 객체 스스로의 판단에 따라 수행하는 [자율적인 행동]이지 외부의 객체가 [니가 알고 있는 객체에게 메시지를 보내]라고 직접적으로 접근하는 것은 내부 구현에 간섭이다.

정리하자면, 자율적인 객체는 자신에게 주어진 책임필요한 정보 를 바탕으로 수행하던 중 어떤 정보에 대해서 알지 못하거나 도움이 필요할 경우 적절한 객체에게 메시지를 전송(위임)하여 협력을 요청한다.

객체는 스스로 판단하고 행동하는 자율적인 존재 라는 의미와 필요한 정보와 정보에 기반한 행동을 함께 가진 존재 라는 의미는 결국 같은 의미이다.


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

객체지향은 객체를 중심에 놓는 프로그래밍 패러다임이다. 여기서 객체란 쌍태와 행동을 함께 캡슐화 하는 실행 단위 이다. 그렇다면 객체가 가질 수 있는 상태와 행동을 어떤 기준 으로 결정해야 할까? 객체를 설계할 때 어떤 행동과 상태를 결정했다면 그 이유는 무엇일까?

애플리케이션 안에 어떤 객체가 필요하다면 그 이유는 단 하나이다. 그 객체가 협력에 참여하고 있기 때문 이다. 그리고 객체가 협력에 참여할 수 있는 이유는 협력에 필요한 적절한 행동을 보유 하고 있기 때문이다.

결론적으로 객체의 행동을 결정하는 것은 참여하고 있는 협력 이다. Movie 라는 객체를 보면 직관적으로 상영하다 라는 행동을 가지고 있을 것 같다. 하지만 우리가 지금껏 살펴본 예제에서 Movie 객체는 요금 계산 을 위한 행동만을 수행한다. 왜? 앞에서 말한 것 처럼 객체의 행동은 참여하고 있는 협력으로부터 결정 되기 때문이다. 앞선 예제는 예매하다 라는 시스템의 책임을 수행하기 위해 각 객체들이 협력을 하고 그 협력 안에서 Movie 객체는 요금 계산 이라는 책임을 진다.

협력이라는 문맥을 고려하지 않고 Movie 의 행동을 결정하는 것은 아무런 의미가 없다. 협력이 존재하기 때문에 객체가 존재 하는 것이다.

객체의 행동을 결정하는 것은 협력 이라면 객체의 상태를 결정하는 것은 행동 이다.

객체의 상태는 그 객체가 행동을 수행하는 데 필요한 정보가 무엇인지로 결정된다.

객체는 자신의 상태를 스스로 결정하고 관리하는 자율적인 존재이기 때문에 객체가 수행하는 행동에 필요한 상태도 함께 가지고 있어야 한다.

Movie 가 기본 요금인 fee 와 할인 정책인 discountPolicy 인스턴스 변수를 상태의 일부로 포함하는 이유는 요금 계산이라는 행동을 수행하는데 이 정보들이 필요 하기 때문이다.

상태는 객체가 행동하는 데 필요한 정보에 의해 결정되고 행동은 협력 안에서 객체가 처리할 메시지로 결정된다. 결과적으로 객체가 참여하는 협력 이 객체를 구성하는 행동과 상태 모두를 결정 한다. 따라서 협력은 객체를 설계하는 데 필요한 일종의 문맥 을 제공한다.


책임

객체를 설계하기 위해 필요한 문맥인 협력 이 갖춰졌다고 하자. 다음으로 할 일은 협력에 필요한 행동을 수행할 수 있는 적절한 객체를 찾는 것 이다. 이 때 협력에 참여하기 위해 객체가 수행하는 행동책임 이라고 한다.

다시한번 짚고가자. 우리가 지금 애기하고 있는 대상은 클래스 가 아니라 객체 이다. 여기서 객체가 수행하는 행동 을 의미하는 것이 클래스의 메서드만 의미하는 것이 아님에 주의하자.

책임 이란 객체에 의해 정의되는 응집도 있는 행위의 집합 으로 객체가 유지해야 하는 정보수행할 수 있는 행동 에 대해 개략적으로 서술한 문장이다.

여기서 개략적으로 서술한 문장 을 주목하자. 위에서 주의사항으로 언급했듯 객체가 수행하는 행동 즉, 책임 은 객체의 관점에서 바라봐야 비로소 와닿는다. 클래스 의 관점에서 아무리 고민해봐야 행동이니 메서드지! 라는 생각밖에 들지 않는다.

책임이란 객체가 유지해야하는 정보와 수행할 수 있는 행동에 대해 개략적으로 서술한 문장이다.

즉 객체의 책임은 객체가 무엇을 알고 있는가(Doing)무엇을 할 수 있는가(Knowing) 로 구성된다.

  • 하는 것(Doing) : 필요한 행동을 수행할 책임
    • 객체를 생성하거나 계산을 수행하는 등 스스로 하는 것 (영화 예매를 하다. 나이를 계산하다.)
    • 다른 객체(협력자)의 행동을 시작시키는 것 (Movie 객체에게 요금 계산을 요청하다.)
    • 다른 객체(협력자)의 활동을 제어하고 조절하는 것
  • 아는 것(Knowing) : 필요한 지식을 알아야 할 책임(정보)
    • 사적인 정보에 관해 아는 것 (fee에 대해 알다.)
    • 관련된 객체에 대해 아는 것 (discountPolicy 객체에 대해 알다.)
    • 자신이 유도하거나 계산할 수 있는 것에 관해 아는 것

‘Doing’책임을 수행하는데 필요한 ‘Knowing’책임을 가진 객체가 누구일까 고민한다

영화 예매 시스템에서 Screening 의 책임은 무엇인가? 영화를 예매하는 것 이다. 이 책임은 다시 하는 것아는 것 으로 분류할 수 있다. 영화를 예매하다.하는 것 과 관련된 책임이다. 그리고 상영 정보(상영할 영화 등)를 알고 있어야 한다.아는 것 과 관련된 책임이다.

다음으로 넘어가 보자 예매를 위해서 영화 가격 계산 이라는 책임을 수행해야 하는데 누가 해야할까? 도메인 모델 을 잘 이해했다면 Movie 에게 영화 가격 계산 책임을 할당할 것이다. 왜그럴까?

뒤에서 더 다루겠지만 책임을 객체에게 할당하는데에 있어서 가장 기본적으로 고려할 사항(원칙이 아니다)은 정보 전문가 에게 할당하는 것이다. 여기서 말하는 정보 전문가알아야 할 책임 즉, 책임을 수행하는 필요한 정보 를 가장 많이 가지고 있을 것 같은 객체를 의미한다.

필요한 정보 는 절대 객체가 인스턴스 변수, 데이터로써 저장하는 상태 와 다름에 주의하자. 다시한번 강조한다. 필요한 정보알아야 할 책임 이다. 절대 상태 와 헷갈려서는 안된다.

그렇다면 이 필요한 정보 는 도대체 어떻게 알게 되는 것일까? 공부를 하면서 이게 가장 혼돈스러웠다. 필요한 정보도메인에 대한 충분한 이해 를 바탕으로 객체 스스로가 자신을 책임진다 라는 맥락에서 곱씹어보면 생각보다 직관적으로 책임을 수행하는 필요한 정보(알아야 할 책임)를 갖는 객체 가 누구인지 파악할 수 있다.

우리는 영화표 예매를 하기위한 도메인 개념에 대해 이미 충분한 파악을 했다. 그렇다면 영화 가격 계산 이라는 책임을 수행하기 위해서는 영화 정보(할인 정책이나 기본 요금) 에 대해 가장 잘 알고있는 객체를 찾아야 하는 것도 잘 알고 있을것이다. 영화 정보 에 대해 가장 잘 알고있는 객체는 누구일까? 개념적으로나 직관적으로나 Movie 객체일 것 같지 않나?

물론 이 영화 정보(할인 정책 및 기본 요금) 에 대해 잘 알고있다라는 의미가 영화 기본 가격은 fee라는 데이터, 할인 정책은 discountPolicy 라는 인스턴스 변수 라는 상태로 구현되는지 알아야 한다는 의미가 아니다. 위에서 언급 했듯 알아야 할 책임자신이 유도하거나 계산할 수 있는 것에 관해 아는 것 도 포함되기 때문에 실제 구현에서는 할인 정책 및 기본요금 이 어떤 계산식을 수행함으로써 얻어질 수도 있다. 아직은 그게 중요하지 않다. 개념적으로, 직관적으로 Movie 객체가 영화 정보(할인 정책 및 기본요금) 을 알아야 할 책임이 있다는 것만 알아도 충분하다.

이토록 필요한 정보를 가진 객체에게 책임을 할당 한다라는 표현에 대해 주저리주저리 길게 늘어놓는 이유는 그만큼 필요한 정보상태 는 결이 다르다는 점을 강조하고 싶어서 이다.

중요한 것은 ‘도메인 개념에 대한 충분한 이해’를 바탕으로 ‘객체가 자신을 스스로 책임진다.’는 기본적인 개념에서 접근한다면 어떤 객체가 어떤 정보를 알고있어야 하는지 꽤나 직관적으로 알 수 있다. -조영호님과의 메일 질답 중 발췌


다시 본론으로 돌아와서 우리는 Screening 객체에게 예매해다. 라는 책임을 할당하고 Movie 객체에게 영화 가격을 계산하다. 라는 책임을 할당했다. Screeningreserve 메시지를 수신하고 movie 를 인스턴스 변수로 포함하는 이유는 협력 안에서 영화를 예매 할 책임을 수행해야 하기 때문이다. Movie 객체가 calculateMovieFee 메시지를 수신할 수 있고 fee, dispatchPolicy 를 상태로 갖는 이유는 협력 안에서 가격을 계산할 책임을 할당받았기 때문이다. 순서에 주의하자. 상태를 가졌기 때문에 책임을 할당받은게 아니라 책임을 할당받았기 때문에 상태를 갖게 된 것이다.

이처럼 협력 안에서 객체에게 할당한 책임이 외부의 인터페이스와 내부의 속성을 결정한다.

일반적으로 책임과 메시지의 크기는 다르다. 책임은 객체가 수행할 수 있는 행동을 종합적이고 간략하게 서술하기 때문에 책임은 메시지보다 추상적이고 개념적으로도 더 크다. 처음에는 단순한 책임이라고 생각했던 것이 여러개의 메시지로 분할되기도 하고 하나의 객체가 수행할 수 있다고 생각했던 책임이 나중에는 여러 객체들이 협력해야만 하는 커다란 책임으로 자라는 것이 일반적이다.

예매하다 라는 책임이 Screening 하나에서 그쳐지지 않고 Movie / DiscountPolicy / DiscountCondition 객체들과 협력함으로써 수행됨을 참고하자.

여기서 중요한 사실은 책임의 관점에서 ‘필요한 정보를 아는 것’과 ‘하는 것’이 밀접하게 연관 되어있다는 점이다. 어떤 책임을 수행하기 위해서는 그 책임을 수행하는데 필요한 정보 도 함께 알아야 할 책임이 있다는 것이다.


책임 할당

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

위에서 언급했듯이 책임을 수행하는 데 필요한 정보알아야 할 책임 에 해당한다. 상태 가 아니다. 그리고 이 필요한 정보 는 도메인에 대해 충분히 이해했을 때 어떤 객체가 알아야 하는 정보가 무엇인지 직관적으로 알 수 있다. 도메인에 대한 충분한 이해협력 이라는 문맥을 충분히 이해해야 하는 것과 다르지 않다.

협력을 설계하는 출발점은 시스템이 사용자에게 제공하는 기능을 시스템이 담당할 하나의 책임 으로 바라보는 것이다. 객체지향 설계는 시스템의 책임을 완료하는 데 필요한 더 작은 책임을 찾아내고 이를 객체들에게 할당하는 반복적인 과정 을 통해 모양을 갖춰간다.

정보 전문가 에 대한 내용을 위에서 한 번 언급했지만 책임 할당이라는 관점에서 한 번 더 정보 전문가에게 책임을 할당하는 방법을 살펴보자. 시스템이 사용자에게 제공해야 할 기능은 영화를 예매 하는 것이고 이 기능을 시스템이 제공할 책임 으로 할당하자. 객체가 책임을 수행하는 유일한 방법은 메시지를 수신 하는 것이므로 책임을 할당 한다라는 것은 메시지의 이름을 결정하는 것과 같다.

예매하다 라는 메시지로 협력을 시작하는 것이 좋을 것 같다.

  1. ‘예매하다’ 라는 메시지를 처리할 적절한 객체는 누구일까?

영화를 예매하는 책임을 어떤 객체에게 할당해야 할까? 기본 전략은 정보 전문가 에게 책임을 할당하는 것이다. 따라서 영화 예매와 관련된 정보를 가장 많이 알 것 같은 객체에게 책임을 할당하는 것이 바람직하다. 영화 예매와 관련된 정보는 상영 시작시간, 러닝타임, 기본요금, 영화 정보 와 같은 상영 정보를 알아야 할 것 같다. 그렇다면 이와같은 상영 정보 를 가장 많이 아는 객체는 누구일까? 직관적으로 Screening 객체임을 어렵지 않게 떠올릴 수 있다.

‘예매하다’에 필요한 정보는 Screening 객체가 가장 많이 알고있을 것 같다.

자 이제 Screening 객체가 예매를 하기 위해 상영 시작 시간 을 구하고 러닝 타임 을 구하고 예매 요금 을 구하고 영화 정보 를 구할 것이다. 근데 이 모든 필요한 것들을 Screening 혼자서 구하기엔 정보가 조금 부족한 것 같다. 도메인으로부터 개념적으로 생각했을때 상영 시작 시간러닝 타임 은 왠지 직접 구할 수 있을 것 같은데 예매 요금 을 직접 계산하는데는 할인정책과 할인조건이 적용된 영화 요금 이 필요하다. 그리고 이러한 영화 요금 을 구하는 데 알아야 하는 정보들은 Screening 에게 필요한 정보를 넘어 선 것 같다. 그렇다면 이제 예매하다 로부터 분할된 책임인 영화 요금을 계산하다 라는 책임은 누구한테 할당함으로써 Screening 과 협력하게 될까?

  1. ‘예매 요금을 계산하다’ 라는 메시지를 처리할 적절한 객체는 누구일까?

다시 정보 전문가 를 찾을 떄가 왔다. 영화 요금을 계산 을 위해서는 영화 기본 요금할인 정책 이 적용된 만큼 계산해야 한다. 즉, 영화 요금을 계산하다 라는 책임을 수행하기 위해서 필요한 정보는 영화 기본 요금 과 어떤 할인 정책 이 적용되었는지 알아야 한다. 이를 가장 잘 알고 있을 만한 객체는 누구일까? 직관적으로 Movie 객체가 영화 요금 계산 에 필요한 정보를 잘 알고 있을 것 같다.

‘영화 요금을 계산하다’ 에 필요한 정보는 Movie 객체가 가장 많이 알고 있을 것 같다.

이제 Movie 객체가 영화 요금 계산 책임을 수행하기 위해서 필요한 정보인 영화 기본 요금 은 잘 알고있지만 할인 요금 에 대해서는 정보전문가가 아니다. 할인 요금을 계산하다 라는 책임이 또 생겼다. 할인 요금을 계산하다 라는 책임을 수행하기 위해서는 할인 금액할인 조건 이 필요하다. 이 정보에 대한 전문가는 할인 정책 이 적절할 것 같다.


조금 성급한감이 없지않아 있다 확 와닿지 않는 부분도 있을 것이다. Movie 라는 개념이 요금을 계산하다 라는 행동을 수행하는게 오히려 비정상 적으로 보일 수 있다. 중요한 것은 협력 이라는 문맥에서 책임 이 결정되는 것이다. 그리고 책임을 할당받은 객체가 현실과는 괴리가 있어 보일지라도 제대로 협력을 수행한다면 정상적이다.

이처럼 객체지향 설계는 협력에 필요한 메시지를 찾고 메시지에 적절한 객체를 선택하는 반복적인 과정 을 통해 이뤄진다. 그리고 이런 메시지가 메시지를 수신할 객체의 책임을 결정 한다.

이렇게 결정된 메시지가 객체의 퍼블릭 인터페이스를 구성한다는 점도 눈여겨 보자. 협력을 설계하면서 객체의 책임을 식별해 나가는 과정에서 최종적으로 얻게 되는 결과물은 시스템을 구성하는 객체들의 인터페이스와 오퍼레이션의 목록 이다.

물론 모든 책임 할당 과정이 이렇게 단순하지는 않다. 어떤 경우에는 응집도와 결합도의 관점에서 정보 전문가가 아닌 다른 객체에게 책임을 할당하는 것이 더 적절한 경우도 있다. 하지만 기본적인 전략은 책임을 수행할 정보 전문가를 찾는 것이다. 정보 전문가에게 책임을 할당하는 것만으로도 상태와 행동을 함꼐 가지는 자율적인 객체를 만들 가능성이 높아지기 때문이다.


책임 주도 설계

지금까지 살펴본 내용의 요점은 협력을 설계하기 위해서는 책임에 초점을 맞춰야 한다는 것이다. 어떤 책임을 선택하느냐가 전체적인 설계의 방향과 흐름을 결정한다. 이처럼 책임을 찾고 책임을 수행할 적절한 객체를 찾아 책임을 할당하는 방식으로 협력을 설계하는 방법을 책임 주도 설계 라고 부른다.

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

  • 시스템 책임을 더 작은 책임으로 분할한다.

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

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

  • 해당 객체 또는 역할에게 책임을 할당함으로써 두 객체가 협력하게 한다.

협력은 객체를 설계하기 위한 구체적인 문맥을 제공한다. 협력이 책임을 이끌어 내고 책임이 협력에 참여할 객체를 결정한다. 책임 주도 설계는 자연스럽게 객체의 구현이 아닌 책임에 집중할 수 있게 한다. 구현이 아닌 책임에 집중하는 것이 중요한 이유는 유연하고 견고한 객체지향 시스템을 위해 가장 필요한 재로가 바로 책임이기 때문이다.


메시지가 객체를 결정한다.

객체에게 책임을 할당하는 데 필요한 메시지를 먼저 식별 하고 메시지를 처리할 객체를 나중에 선택 하는것이 중요하다. 다시말해 객체가 메시지를 선택하는 것이 아니라 메시지가 객체를 선택하는 것이다.

메시지가 객체를 선택해야 하는 중요한 이유가 두 가지 있다.

  1. 객체가 최소한의 인터페이스 를 가질 수 있게 된다. 필요한 메시지가 식별될 때 까지 객체의 퍼블릭 인터페이스에 어떤것도 추가하지 않기 때문에 객체는 꼭 필요한 크기의 퍼블릭 인터페이스를 가질 수 있다.

  2. 객체는 충분히 추상적인 인터페이스 를 가질 수 있게 된다. 인터페이스는 what(무엇) 을 하는지 표현해야 하지만 how(어떻계) 수행해야하는지 노출해서는 안된다. 메시지는 외부의 객체가 요청하는 무언가를 의미하기 때문에 미시지를 먼저 식별하면 무엇을 수행할지에 초점을 맞추는 인터페이스를 얻을 수 있다.


행동이 상태를 결정한다.

객체가 존재하는 이유는 협력에 참여하기 위해서다. 따라서 객체는 협력에 필요한 행동을 제공해야 한다. 객체를 객체답게 만드는 것은 객체의 상태가 아니라 다른 객체에게 제공하는 행동이다.

객체의 행동은 객체가 협력에 참여할 수 있는 유일한 방법 이다. 객체가 협력에 적합한지를 결정하는 것은 그 객체의 상태가 아니라 행동이다. 얼마나 적절한 객체를 창조했느냐는 얼마나 적절한 책임을 할당했느냐에 달려있고, 책임이 얼마나 적절한지는 협력에 얼마나 적절한가에 달려있다.

만일 객체의 행동이 아니라 상태에 초점을 맞추게 된다면 객체에 필요한 상태가 무엇인지를 먼저 결정하고 그 후에 상태에 필요한 행동을 결정하게 된다. 이런 방식은 객체의 내부 구현이 객체의 퍼블릭 인터페이스에 노출되게 만들기 때문에 캡슐화 를 저해한다.

캡슐화 를 위반하지 않도록 구현에 대한 결정을 뒤로 미루면서 객체의 행위를 고려하기 위해서는 항상 협력 이라는 문맥 안에서 객체를 생각해야 한다. 협력 관계 속에서 다른 객체에게 무엇을 제공해야 하고 다른 객체로부터 무엇을 얻어야 하는지를 고민해야만 훌륭한 책임을 수확할 수 있다.

참고 및 출처

  • 오브젝트