▼ What ?
이 "협력하는 객체들의 공동체" 라는 챕터에선 실세계를 모방하여 '객체 지향' 이라는 세계를 이해하도록 하는 내용들을 담고 있다.
▼ Summory & Comment
이 챕터를 읽고 나서 기억에 남는 말 !
객체지향은 객체를 지향하는 것이지 클래스를 지향하는 것이 아니다.
객체지향의 세계는 어떤 곳인가 ?
- " 객체지향이란 실세계를 직접적이고 직관적으로 모델링할 수 있는 패러다임 "
그럼, 객체지향의 목표는 실세계를 모방하는 것 ?
➜ 철학적인 관점에선 맞는 말이지만, 유연하고 실용적인 관점에선 적합 X
객체지향의 목표는 고객과 사용자를 만족시킬 수 있는 신세계를 창조하는 것 !
- 그럼에도 실세계 객체와 소프트웨어 객체를 대응시키는 이유는?
➜ 실세계에 대한 비유가 객체지향의 다양한 측면을 이해하고 학습하는 데엔 매우 효과적이기 때문이다
- 이번 챕터에서만 실세계의 모방이라는 전통적인 관점에서 객체지향의 다양한 개념을 다룰 것 !
역할 · 책임 · 협력
- 우리 실생활에서 일어나는 커피 주문이라는 협력 관계를 통해 객체지향의 개념을 알아보자
- 손님 ➜ 캐시어 (커피 주문 요청) / 캐시어 ➜ 바리스타 (커피 제조 요청)
/ 바리스타 ➜ 캐시어 (커피 완성 응답) / 캐시어 ➜ 손님 (커피 완성 응답)
- 이처럼 손님이 주문한 커피를 제조하기 위해 캐시어와 바리스타가 협력하는 과정에선 여러 요청과 응답이 발생한다 !
➜ 협력은 요청과 응답을 통해 이뤄진다
- 이처럼 손님이 주문한 커피를 제조하기 위해 캐시어와 바리스타가 협력하는 과정에선 여러 요청과 응답이 발생한다 !
- 손님 ➜ 캐시어 (커피 주문 요청) / 캐시어 ➜ 바리스타 (커피 제조 요청)
- 협력을 위해 사람들은 '손님', '캐시어', '바리스타' 라는 특정한 역할을 부여받는다 !
➜ 역할을 맡게 되는 순간, 특정 책임을 수행해야 한다
➜ 특정한 역할은 특정한 책임을 암시 !
( 역할은 관련성이 높은 책임의 집합 )
- 이러한 과정으로 인해 몇 가지의 중요한 개념이 등장한다
- 여러 사람이 동일한 역할을 수행 가능
➜ 역할은 대체 가능하다 ! - 커피 제조 요청을 받아도 사람에 따라 독특한 방법으로 커피를 제조 갸능
➜ 사람(객체)이 책임을 수행하는 방법은 자율적으로 선택 가능하다 !
( 다형성: 동일한 요청에 대해 서로 다른 방식으로 응답할 수 있는 능력 ) - 캐시어가 바리스타라는 역할도 동시에 수행 가능
➜ 한 사람(객체)이 동시에 여러 역할을 수행 가능하다 !
- 여러 사람이 동일한 역할을 수행 가능
- 이러한 과정으로 인해 몇 가지의 중요한 개념이 등장한다
- 객체지향이라는 문맥으로 가져와보면 ?
- 사람 ➜ 객체 / 에이전트의 요청 ➜ 메시지 / 요청을 처리하는 ➜ 메서드
- 객체지향 설계는 "적절한 객체에게 적잘한 책임을 할당" 하는 것에서 시작 !
- 사람 ➜ 객체 / 에이전트의 요청 ➜ 메시지 / 요청을 처리하는 ➜ 메서드
객체가 갖춰야 하는 " 두 가지 덕목 "
- 객체는 충분히 '협력적' 이어야 한다
➜ 다른 객체의 요청에 응답할 줄도, 다른 객체에 요청할 줄도 알아야 한다다른 객체의 명령에 복종
➜ 요청에 응답하는 것, 응답 여부나 방식은 스스로 결정
- 객체는 충분히 '자율적' 이어야 한다
- 이 점들을 통해서도 객체의 사회와 인간의 사회가 유사함을 알 수 있다
객체가 뭘까 ?
- " 상태(state)와 행동(behavior)을 함께 지닌 실체 "
➜ 협력 속에서 스스로 판단하여 행동하고, 그 행동엔 어떤 상태가 필요한가를 알고 있어야 한다
- 객체의 내부와 외부를 명확하게 구분해야 객체의 자율성을 보장 !
➜ 다른 객체가 '무엇(what)'을 수행하는지는 알지만 '어떻게(how)' 수행하는지에 대해선 알 수 없다
- 객체는 상태와 행위를 하나의 단위로 묶는 자율적인 존재이다
➜ 전통적인 개발 방법(데이터와 프로세스를 분리)과 객체지향을 구분 짓는 핵심적 요인 !
인간과 객체의 한 가지 차이점
- 인간은 요청을 위해 다양한 방법(말, 메모 등)을 활용
➜ 객체는 오직 한 가지 의사소통 수단으로 송 · 수신하는 메시지만 존재한다 !
- 메서드(method)는 이런 메시지를 처리하는 방법을 말한다 !
- 다른 프로그래밍 언어(절차지향) ≠ 객체지향 프로그래밍 언어
➜ 컴파일 시간이 아닌 실행 시간에 메시지를 수신한 객체가 실행 시간에 메서드를 선택할 수 있다는 점
- "메시지(커피 제조 요청)" 와 "메서드(커피 제조하는 구체적인 방법)" 의 분리
( 캡슐화(encapsulation) )
➜ 캐시어(객체)은 커피가 제조될 것이라고 기대만 할 뿐 커피를 제조하는 방법에는 관심 X
➜ 바리스타(객체)의 자율성이 보장된다 !
객체지향이 뭘까 ?
- " 시스템을 협력(상호작용)하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법 "
- 자율적인 객체 ➜ 상태 + 행위 + 스스로를 책임지는 것
- 객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력
➜ 협력 내에서 정해진 역할(관련도가 높은 책임의 집합)을 수행
➜ 협력하기 위해 메시지를 전송해 요청하고, 수신한 메시지를 처리하는 데 적합한 메서드를 자율적으로 선택 !
- 자율적인 객체 ➜ 상태 + 행위 + 스스로를 책임지는 것
객체지향의 핵심은 클래스가 아닌 객체이다 !
앞선 내용들은 이 말을 전달하고 이해시키기 위한 서론이었다고 생각한다
- 많은 사람들이 객체지향이라는 말을 들으면 '클래스' 라는 단어를 먼저 떠올린다
- 에스키모인들의 언어엔 눈을 의미하는 어휘가 2개에 불과하지만 400여개가 있다고 부풀려졌던 일화
➜ 클래스도 마찬가지로, 초기 객체지향 프로그램의 초점이 클래스라는 빌딩 블록에 맞춰짐으로써 사회에 클래스에 대한 중요성이 과하다 싶을 정도로 강조되고 부풀려졌다 ..
- 에스키모인들의 언어엔 눈을 의미하는 어휘가 2개에 불과하지만 400여개가 있다고 부풀려졌던 일화
- 자바스크립트 같은 프로토타입(prototype) 기반의 객체지향 언어에선 클래스가 존재하지도 않고, 상속 역시 클래스가 아닌 객체 간의 위임(delegation) 메커니즘을 기반으로 한다 !
- 지나치게 클래스에 집중했을 때,
➜ 객체의 캡슐화를 저해하고 클래스를 서로 강하게 결합시킨다
애플리케이션을협력하는 객체들의 공동체가 아닌 클래스로 구성된 설계도로 봤을 때,
➜ 유연하고 확장 가능한 애플리케이션의 구축을 방해한다
- 코드를 담는 클래스의 관점에서 "메시지를 주고받는 객체의 관점" 으로 사고의 중심을 전환하자 !
어떤 클래스가 필요한가 ?( 클래스 = 객체들의 협력 관계를 코드로 옮기는 도구 )
➜ 어떤 객체들이 어떤 메시지를 주고받으며 협력하는가 ?클래스들의 정적인 관계
➜ 객체들의 동적인 관계 !- 클래스가 중요하지 않다는 것이 아니라.. 협력 구조와 책임을 식별하는 것에 비해 덜 중요하다는 것 !
- 클래스의 구조와 메서드가 아닌 객체의 " 역할, 책임, 협력 " 에 집중하자 !
▼ Study
Issue_1
'메시지를 수신한 객체가 실행 시간에 메서드를 선택할 수 있다는 점은 다른 프로그래밍 언어와 객체지향 프로그래밍 언어를 구분 짓는 핵심적인 특징 중 하나다. 이것은 프로시저 호출에 대한 실행 코드를 컴파일 시간에 결정하는 절차적인 언어와 확연히 구분되는 특징이다.'
메서드를 선택한다는 것이 정확히 어떤 의미인지 잘 모르겠네요.
- 메서드를 선택한다는 것은 상황에 따라 적합한 메서드를 자율적으로 선택해 호출한다는 의미인 것 같습니다.
Issue_2
중요한 것은 클래스들의 정적인 관계가 아니라 메세지를 주고받는 객체들의 동적인 관계다.
여기서 클래스는 왜 정적인 관계이고, 객체는 동적인 관계 인건가요?
- 주어진 역할에 따라 책임을 수행하고 역할 간에 메시지를 주고 받으며 유연하고 견고한 협력관계를 구축하는 객체는 동적인 관계라 할 수 있지만, 저자가 앞서 "클래스는 객체들의 협력 관계를 코드로 옮기는 도구에 불과하다." 라고 말했듯이 클래스는 객체와 달리 정적인 관계라 말하는 것 같습니다.
Issue_3
실세계의 사물을 기반으로 소프트웨어 객체를 식별하고 구현까지 이어간다는 개념은 객체지향 설계의 핵심 사상인 '연결완전성(seamlessness)'을 설명하는 데 적합한 틀을 제공한다.
연결완전성이 무엇을 의미하는지 잘 모르겠어요.
- "실세계의 사물을 기반으로 소프트웨어 객체를 식별하고" 라는 말을 생각해보면, 실세계를 모델링한 소프트웨어를 개발할 때에 우선적으로 어떤 객체가 실제 세계에선 무엇을 나타내는지 명확하게 식별해야 한다는 것 같습니다. 그리고 이렇게 식별한 객체를 실제로 구현해내면, 소프트웨어 상의 객체와 클래스를 실세계의 객체와 상황에 맞게 설계한 소프트웨어를 개발할 수 있게 되는 것입니다. 이러한 과정을 거쳐서 구현된 소프트웨어 시스템은 매끄럽게(seemless) 작동할 수 있게 되는 것이고, 이때 연결 완전성을 만족한다고 하는 것 같습니다.
Issue_4
32p 밑에서 3번째 줄, 객체를 상태와 행동을 지닌 실체라고 정의한다고 하는데 상태를 멤버 변수, 행동을 메서드로 비유해서 생각해도 될지 잘 모르겠네요!
이렇게 생각했을 때 애매했던 부분이 저자가
커피를 제조하는 바리스타가 제조 방법을 모른다는 것이 말이 되지 않는 것처럼 객체가 어떤 행동을 하기 위해 필요한 상태를 알지 못하는 것 역시 말이 되지 않는다.
여기서 멤버 변수가 어떤행동을 하기 위해 필요한 상태라고 할 수 있는지 의문입니다!
- 상태로 꼭 멤버변수, 행동으로 꼭 메서드로 한정시킬 필요는 없다고 생각해요. 저자가 전달하고자 하는 바는 이 책에서 강조한 자율적인 객체가 되기 위해선 객체가 어떤 행동을 할 때 그 행동을 하는데 필요한 상태를 아는 것이 중요하다는 것 같아서, 객체를 구상할 때 이 점들을 유의해야 한다는 정도로 알면 괜찮을 것 같습니다!
Issue_5
메시지를 수신한 객체가 실행 시간에 메서드를 선택할 수 있다는 점은 다른 프로그래밍 언어와 객체지향 프로그래밍 언어를 구분 짓는 핵심적인 특징 중 하나다. 이것은 프로시저 호출에 대한 실행 코드를 컴파일 시간에 결정하는 절차적인 언어와 확연히 구분되는 특징이다.
여기서 실행 시간에 메서드를 호출하는 것과 컴파일 시간에 메서드를 호출하는 것이 어떤 차이가 있는지 잘 모르겠습니다.
- 정적 언어에서는 일반적으로 컴파일 시점에 타입체크가 이뤄지고, 메서드 호출이 결정됩니다. 하지만, 객체지향 언어는 실행 시간에 메서드를 선택해 다형성을 구현할 수 있습니다. 그래서 어느 시점에 메서드를 호출하냐에 따라서 다형성의 유무가 결정되기 때문에, 이러한 점이 정적 언어와 구분되는 특징이라고 하는 것 같습니다.