객체지향의 사실과 오해-역할,책임,협력 관점에서 본 객체지향
SCRAPS
[27] 역할은 어떤 협력에 참여하는 특정한 사람이 협력 안에서 차지하는 책임이나 임무를 의미한다. 어떤 사람이 손님이라는 역할을 맡았다면, 그 사람은 커피를 주문하는 임무를 맡게된다. 캐시어라는 역할을 맡은 사람은 손님으로부터 주문을 받아야만 한다. 바리스타 역할을 맡은 사람은 주문된 커피를 제조해야 할 책임이 있다.
카페가 제대로 돌아가기 위해선 역할이라는 구조를 잘 설계해 놓은 뒤 주어진 역할에 맞는 책임을 다할 직원을 할당해야 한다. 직원이 어떤 사람이던 간에 역할은 변치 않으며, 심지어 어제 봤던 직원이 오늘 다른 사람으로 대체되어도 같은 역할과 책임을 충실히 다한다면 이 카페는 문제가 없는 것이다. 일종의 호환성 인 것이다.
[38] 객체지향의 중심에는 클래스가 아니라 객체가 위치하며, 중요한 것은 클래스들의 정적인 관계가 아니라 메시지를 주고받는 객체들의 동적인 관계이다.
클래스와 객체, 무슨 차이냐고? 클래스는 코드를 담는 그릇이고, 객체는 역할을 수행하는 직원이라는 점이다. 카페가 운영되려면 직원이 필요하다. 객체지향 애플리케이션이 동작하려면 객체가 필요하다.
객체 간의 동적인 관계는 곧 책임을 수행하기 위해 필요한 방법(메서드)를 자율적으로 선택할 수 있느냐의 차이에 있다. 클래스는 그 자리에 로직이 고정되어있지만 객체는 로직을 자율적으로 선택할 수 있다.
[46]
-
객체는 상태를 가지며 변경가능하다 (mutable). 반면에 값은 상태를 가지지 않고 불변하다. 마치 1은 영원히 1인 것처럼.
-
앨리스의 상태를 변경시키는 것은 앨리스의 행동 뿐이다. 객체가 함부로 다른 객체의 상태를 바꾸는 것은 결합도를 높이고 캡슐화를 잃게된다.
-
행동의 결과는 상태에 의존적이며, 상태를 이용해 서술할 수 있다.
-
행동의 순서는 결과에 영향을 미친다.
-
앨리스는 어떤 상태에 있더라도 유일하게 식별 가능하다. 식별자는 immutable 하다.
-
객체지향 이지, 클래스 지향이 아니다. 클래스는 객체를 정의하는 문서이자 구조일 뿐이며, 중요한 것은 객체의 책임과 다른 객체와의 협동, 관계를 구축하는 일이다. 클래스를 사용하지 않는 객체지향 언어도 있다. JS는 프로토타입이라는 것으로 객체의 책임을 위임한다.
[55]
객체의 모든 행동은 상태를 변화시키는가? - 아니오. 행동에는 상태변화와 메시지 전송이 있다. 메시지 전송 자체는 상태변화를 하지않는다.
객체 간의 유연한 협력과 객체 스스로의 높은 자율성은 상태의 캡슐화의 정도에 따른다.
- 행동의 두 가지 관점:
- 자신의 상태를 변경
- 외부로의 메시지 전송
객체의 프로퍼티는 객체의 상태를 구성하는 특징의 집합이다. 객체의 속성(attribute)은 객체 상태중 값에 해당하는 것이다. 객체의 링크는 객체가 메시지를 보낼 수 있는 대상과의 연결 관계이다. 따라서 프로퍼티는 객체의 속성과 링크를 포함한 개념이다.
[65]
애플리케이션에 필요한 협력을 생각하고 협력에 참여하는 데 필요한 행동을 생각한 후 행동을 수행할 객체를 선택하는 방식으로 수행된다.
구인광고에 보면 '영상편집에 실력이 있는 사람을 뽑습니다' 라고 나와있듯이 행동에 역할을 부여하는 것이 훨씬 자연스럽다.
행동이 상태를 결정한다.
69 '이 객체는 전화기 처럼 행동해요' - 은유를 사용하여 현실객체의 의미 일부를 소프트웨어 객체의 행동을 묘사하여 객체를 바라보는 시선을 바꿀 수 있게된다.
77 복잡한 세상을 단순하게 바꾸는 작업을 추상화 라고 한다. 복잡성을 다루기 위해 추상화는 두 차원에서 이루어진다.
- 구체적인 사물들 간의 공통점을 취하고 차이점은 버린다: 일반화
- 중요한 부분을 강조하고 부차적인 사항을 제거하라
객체라는 추상화를 통해 현실의 복잡성을 극복한다.
87 분류라는 행위를 통해 객체를 공통적인 특징들로 묶인 개념집합으로 위치시킬 수 있으며, 개발자에게 객체들을 더 빨리 찾고 조작할 수 있는 정신적인 지도를 제공해 줄 수 있다.
94 객체지향 시스템에서 동일한 개념집합에 속한 객체들을 하나의 '타입'에 속한 인스턴스로 구현할 수 있다. 즉, 개념은 타입이다. 객체가 동일한 타입을 갖기 위해선 동일한 행동, 동일한 메시지 송수신을 지원하여야 함을 의미하고, 이는 객체지향의 다형성을 의미한다.
97 일반화와 특수화: 일반화 관계는 더 포괄적인 역할을 의미한다. 특수화 관계는 더 구체적이고 역할의 개수가 일반적인 모델에 비해 더 많다.
102 "타입은 시간에 따라 동적으로 변하는 앨리스의 상태를 시간과 무관한 정적인 모습으로 다룰 수 있게 해준다." - 정적타입
105 그러면 클래스는 뭐냐? 클래스는 많은 객체지향 언어들이 차용하는 타입의 구현을 지원하기 위한 매커니즘을 의미한다. 때론 클래스는 코드의 재사용에 사용 되기도 하기 때문에 타입==클래스
라고 생각할 순 없다.
객체의 행동을 분류하기 위해 타입이 도입되었다는 점만 알아두고 가자.
[137]
테스트에 필요한 간접 입력 값을 제공하기 위해 스텁(stub)을 추가하거나 간접 출력 값을 검증하기 위해 목(mock) 객체를 사용하는 것은 객체와 협력해야 하는 협력자에 관해 고민한 결과를 코드로 표현한 것이다.
- STUB: 가짜입력
- MOCK: 가짜출력
[180] 자주 변경되는 기능이 아니라 안정적인 구조를 따라 역할 책임 협력을 구성하라.
[194] 유스케이스는 하나의 시나리오가 아니라 사용자의 목표와 관련된 모든 시나리오의 집합이라는 사실을 알 수 있다.