메시지를 따라라
객체지향의 핵심, 메시지
협력을 위한 유일한 수단
클래스 간 상속관계를 핵심으로 생각하는 잘못된 관점이 존재한다. 하지만 객체지향은 '객체'지향이지 클래스 지향이 아니다. 그래서 클래스가 없는 객체지향 언어도 있다.
클래스는 동적인 객체들의 특성과 행위를 정적인 텍스트로 표현하기 위해 사용할 수 있는 추상화 도구일 뿐이다.
객체지향 설계는 메시지를 주고 받는 동적인 객체들 관점에서 설계
객체지향 설계의 중심에는 메시지가 위치
객체가 메시지를 선택하는 것이 아닌
메시지가 객체를 선택해야 한다.(적절한 객체에게 적절한 책임 분배)
책임-주도 설계 다시 살펴보기
책임을 완수하기 위해 협력하는 객체들을 이용해 시스템을 설계하는 방법을 책임-주도 설계라고 한다.
필요한 책임(행동)을 먼저 정의한다.
그리고 그 책임을 수행할 객체를 선정한다.(메시지 수신은 그 객체에게 부여된 책임)
맡은 책임을 그 객체가 수행할 수 없다면 다른 객체에게 요청을 한다.(책임 연쇄)
이를 반복한다.
What/Who 사이클
어떤 행위가 필요한지를 먼저 결정한 후 이 행위를 수행할 객체를 결정하는 것을 What/Who 사이클이라 한다.
What(행위) Who(객체)
이과정에서 상태는 중요치 않다. 즉, 어떤 객체가 특정 특성을 가졌다고 해서 반드시 그와 관련된 행위를 수행할 것이라고 가정하지 않는다.
협력이라는 문맥 안에서 객체의 책임을 결정하라.
시스템이 수행해야 하는 전체 행위는 협력하는 객체들의 책임으로 분배된다.
묻지 말고 시켜라
메시지를 먼저 결정하고 객체가 메시지를 따르게 하는 설계 방식은 객체가 외부에 제공하는 인터페이스가 독특한 스타일을 따르게 한다. 이를 Tell, Don't Ask 또는 데메테르 법칙이라 한다
메시지를 결정하는 시점에서 어떤 객체가 메시지를 수신할 것인지를 알 수 없다. 때문에 메시지 송신자는 메시지 를 수신할 객체의 내부 상태를 볼 수 없다.
이는 메시지 수신자의 캡슐화를 의미한다.
이는 느슨한 결합을 의미한다.
묻지 말고(내부 구체적인 동작방식= how) 시켜라(요청= 메시지)
객체의 자율성 증가
어떻게 해야하는지 지시하지 말고 무엇을 해야하는 지를 요청하는 것은 인터페이스 크기 감소를 가져온다.
인터페이스 크기가 작다는 것은 해당 객체에게 외부에서 의존하는 부분이 적다는 것이다
메시지를 믿어라
메시지는 전송하는 객체 관점에서 수신하는 객체가 의도한 대로 처리만 할 수 있기만 하면된다. 구체적인 방법은 중요하지 않다. 즉, 수신하는 객체가 변경되어 다른 방법을 취하더라도 처리만 되면 그만이다.
유연하고 재사용성이 높아진다.
객체 인터페이스
인터페이스
인터페이스란 어떤 두 사물이 마주치는 경계 지점에서 서로 상호작용할 수 있게 이어주는 방법이나 장치
인터페이스 세 가지 특징
첫째, 인터페이스의 사용법을 익히기만 하면 내부 구조나 동작 방식을 몰라도 쉽게 대상을 조작하거나 의사를 전달할 수 있다.
둘째, 인터페이스 자체는 변경하지 않고 단순히 내부 구성이나 작동 방식만을 변경하는 것은 인터페이스 사용자에게 어떤 영향도 미치지 않는다.
셋째, 대상이 변경되더라도 동인한 인터페이스를 제공하기만 하면 아무런 문제 없이 상호작용할 수 있다.
자동차를 운전할 때 패달, 핸들 정도만 조작할 줄 알면 된다. 엔진이 어떻게 구성되어 있는지 알필요가 있는가?
자동차 수리로 내부 부품이 변경되어도 운전하는데 문제 없다.
또한 다른 자동차로 변경되어도 운전에는 무리가 없다.
인터페이스를 통한 상호작용이 중요하다.
메시지가 인터페이스를 결정한다.
객체 간 협력을 위한 유일한 방법은 메시지
객체가 수신할 수 있는 메시지 목록이 인터페이스 모양이 된다.
공용 인터페이스
지금까지는 전부 공용 인터페이스를 기본으로 말했다.
외부에 공개된 인터페이스를 공용 인터페이스라 한다.
사적인 인터페이스도 존재한다. 다만 사적인 인터페이스는 객체 자신과의 메시지 상호작용이다.
책임, 메시지, 그리고 인터페이스
객체의 책임이 자율적이어야 한다.
객체가 수행할 구체적인 행동에 대한 자율성
메시지로 구성된 공용 인터페이스는 객체의 외부와 내부를 명확하게 분리한다.
인터페이스와 구현의 분리
객체 관점에서 생각하는 방법
맷 와이스펠드의 객체지향적인 사고 방식 이해를 위한 세 가지 원칙
좀 더 추상적인 인터페이스
객체의 구현에 대한 자율성 보장
최소 인터페이스
외부에 노출될 메서드를 최소한
의존성 저하로 결합도와 재사용성 혜택
노출 최소화로 캡슐화
인터페이스와 구현 간에 차이가 있다는 점을 인식
구현
객체지향에서 내부 구조와 작동 방식을 가리키는 용어
객체를 구성하지만 공용 인터페이스에 포함되지 않는 모든 것
인터페이스에 정의된 선언부를 제외한 모든 것
메서드 구현부, 변수
인터페이스와 구현의 분리 원칙
separation of interface and implementation
객체 외부에 노출되는 인터페이스와 객체의 내부에 숨겨지는 구현을 명확하게 분리
두 개의 분리된 요소로 분할해 설계하는 것(외부 공개 인터페이스와 내부에 감춰지는 구현)
느슨한 결합을 보장
인터페이스와 구현을 분리한다는 것은 변경될 만한 부분을 객체의 내부에 꽁꽁 숨겨 놓는다는 것을 의미 (캡슐화)
따라서 변경에 유리
캡슐화
객체의 자율성을 보존하기 위해 구현을 외부로부터 감추는 것
객체는 상태와 행위를 캡슐화함으로써 협력속에서 자율적인 존재가 될 수 있다.
캡슐화를 정보 은닉이라고 부르기도 한다.
상태와 행위의 캡슐화
객체 = 상태 + 행위
객체는 자신의 상태를 스스로 관리하며 상태를 변경하고 외부에 응답할 수 있는 행동을 내부에 함께 보관한다.
이 중에서 외부에서 반드시 접근해야만 하는 행위만 골라 공용 인터페이스를 통해 노출
전통적인 개발에서는 데이터와 프로세스를 엄격히 분리
객체지향에서는 데이터와 프로세스를 객체라는 하나의 틀 안으로 함께 묶어 객체의 자율성을 보장
사적인 비밀의 캡슐화
캡슐화를 통해 변경이 빈번하게 일어나는 불안전한 비밀을 안정적인 인터페이스 뒤로 숨긴다.
공용 인터페이스를 수정하지 않는 한 자신과 협력하는 외부 객체에 영향을 미치지 않고 내부의 구현을 자유롭게 수정할 수 있다.
이것은 인터페이스와 구현의 분리원칙과 연결된다.
구현 변경에 의한 파급효과를 최대한 억눌른다.
객체를 자율적인 존재로 만든다 = 내부와 외부를 엄격히 분리한다.
책임의 자율성이 협력의 품질을 결정한다
첫쨰, 자율적인 책임은 협력을 단순하게 만든다.
구체적인 구현을 감춤으로써 핵심만 간략히 할 수 있다.
둘째, 자율적인 책임은 모자 장수의 외부와 내부를 명확하게 분리한다.
책임만 보장하면 된다. 책임을 어떻게 수행할지는 자유이다.
사적인 부분이 캡슐화되기 때문에 인터페이스와 구현이 분리된다.
셋째, 책임이 자율적일 경우 책임을 수행하는 내부적인 방법을 변경하더라도 외부에 영향을 미치지 않는다.
요청자는 메시지 수신자에 내부를 볼 수도 알 수도 없다.
이는 변경되어도 요청자는 변경됐다는 사실조차 알 수가 없다.
결국 메서드의 결합도가 객체의 결합도에 영향을 미친다.
넷째, 자율적인 책임은 협력의 대상을 다양하게 선택할 수 있는 유연성을 제공한다.
책임이 자율적일수록 협력이 좀 더 유연해지고 다양한 문맥에서 재활용될 수 있다.
다섯째, 객체가 수행하는 책임들이 자율적일수록 객체의 역할을 이해하기 쉬워진다.
책임이 자율적일수록 적절하게 '추상화'되며, '응집도'가 높아지고, '결합도'가 낮아지며, '캡슐화'가 증진되고, '인터페이스와 구현이 명확히 분리'되며, 설계의 '유연성'과 '재사용성'이 향상된다.
'IT책, 강의 > 객체지향의 사실과 오해(역할, 책임, 협력 관점에서 본 객체지향)' 카테고리의 다른 글
06 객체 지도 - 2 (0) | 2022.12.29 |
---|---|
06 객체 지도 - 1 (1) | 2022.12.24 |
05 책임과 메시지 -1 (0) | 2022.12.19 |
04 역할, 책임, 협력 - 2 (0) | 2022.12.16 |
04 역할, 책임, 협력 - 1 (0) | 2022.12.13 |