조영호님의 책 오브젝트를 보며 정리한 내용입니다.
문제가 될 시 해당글 삭제하겠습니다.
객체지향에서 애플리케이션의 가장 중요한 재료는 클래스가 아닌, 객체들이 주고받는 메시지이다!
객체가 수신하는 메시지들이 객체의 퍼블릭 인터페이스를 구성한다.
[협력과 메시지]
클라이언트 서버 모델
- 두 객체 사시의 협력 관계를 설명하기 위해 사용하는 전통적인 모델
- 협력은 클라이언트가 서버의 서비스를 요청하는 단방향 상호작용이다.
- 객체가 독립적으로 수행할 수 있는 것보다 더 큰 책임을 수행하기 위해서 다른 객체와 협력해야 한다!
[메시지와 메시지 전송]
- 메시지 전송 or 메시지 패싱 : 한 객체가 다른 객체에게 도움을 요청하는 것.
- 메시지 전송자(클라이언트) : 메시지를 전송하는 객체
- 메시지 수신자(서버) : 메시지를 수신하는 객체
- 메시지의 구성 : 오프레이션명 + 인자
- 메시지 전송의 구성 : 오퍼레이션명 + 인자 + 메시지 수신자
- 메서드 : 메시지를 수신했을 때 실제로 수행되는 함수 또는 프로시저
- 동일한 메시지를 전달하더라도, 객체의 타입에 따라 실행되는 메서드는 달라질 수 있다!!
- 전통적인 방식의 개발자는 어떤 코드가 실행될지 정확하게 알고 있는 상황에서 함수 호출 구문을 작성한다.
(전통적인 방식의 개발자는 코드의 의미가 컴파일 시점, 런타임 시점에 동일하다) - 반면 객체는 메시지와 메서드라는 서로 다른 개념을 실행 시점의 연결해야 한다!
(객체지향 방식의 개발자는 코드의 의미가 컴파일 시점, 런타임 시점에 달라질 수 있다)
(이러한 구분은 클라이언트와 서버가 느슨하게 결합될 수 있도록 한다! == 확장에 유리)
[퍼블릭 인터페이스와 오퍼레이션, 시그니처]
- 퍼블릭 인터페이스 : 객체가 의사소통을 위해서 외부에 공개하는 메시지의 집합.
- 오퍼레이션 : 퍼블릭 인터페이스에 포함된 메시지.
- 시그니처 : 오퍼레이션이나 메서드의 명세를 나타낸 것으로 이름과 인자의 목록을 포함한다.
[인터페이스와 설계 품질]
- 퍼블릭 인터페이스 품질에 영향을 미치는 원칙과 기법
1. 디미터 법칙
- 객체 내부 구조에 강하게 결합되지 않도록 협력 경로를 제한하는 것(오직 인접한 이웃하고만 말하라!)
- 위 설명이 어려울 수 있기에 다음 조건에 해당하는 인스턴스에만 메시지를 전송하도록 하자!
1. this 객체
2. 메서드의 매개변수
3. this 속성
4. this의 속성인 컬렉션의 요소
5. 메서드 내에서 생성된 지역 객체
-> 디미터 법칙을 따르지 않았을 시 기차 충돌 이라 불리는 않좋은 코드를 짜게 된다.
ex) screening.calulcateFee(audienceCount);
-> 디미터 법칙을 통해 부끄럼타는 코드를 작성할 수 있다.
(불필요한 어떤 것도 공유하지 않고, 다른 객체의 구현에 의존하지 않는 코드)
(캡슐화하기 위해 따라야 하는 구체적인 지침을 제공한다)
2. 묻지 말고 시켜라
- 훌륭한 객체의 상태에 관해 묻지 말고 원하는 것을 시켜야 한다!
- 메시지 전송자는 메시지 수신자의 상태를 기반으로 결정을 내린 후 메시지 수신자의 상태를 바꿔서는 안된다!!!!!!!
-> 객체의 상태를 변경하는 것은 메시지 수신자의 책임이다!!!!!
- 묻지 말고 시키는 것에 추가적으로 객체가 어떻게 작업을 수행하는지 노출시켜서는 안된다!!!!
-> 어떻게 하는지가 아닌 무엇을 하는지를 서술해야 한다!
3. 의도를 들어내는 인터페이스
- 메서드의 이름을 지을 때 어떻게가 아닌 무엇을 하는지를 드러내야 한다!
(클라이언트 입장에서 동일한 작업을 수행하는 메서드들을 묶을 수 있다)
(의도를 드러내는 선택자(Intention Revealing Selector) -> 의도를 드러내는 인터페이스(Intention Revealing Interface))
- 클라이언트의 의도를 드러낼 수 있는 인터페이스 이름을 선택하자
4. 명령 쿼리 분리 원칙
- 루틴 : 절차를 묶어 호출이 가능하도록 이름을 부여한 기능 모듈
- 프로시저 == 명령 : 부수효과를 발생시킬 수 있지만, 값을 반환할 수 없다.(Update / Delete)
-> 프로지저와 명령은 해당 메서드를 호출할 때는 부수효과에 대해서 항상 고민해야한다!!!
- 함수 == 쿼리: 값을 반환할 수 있지만 부수효과를 발생시킬 수 없다. (Select)
- 명령 쿼리 분리 원칙을 한 문장으로 표현하면 "질문이 답변을 수정해서는 안된다!" 는 것이다!
- 명령 쿼리 분리 원칙을 지켜야하는 이유!
- 한 메서드 안에 명령 쿼리가 함께 있다면, 너무나 고치기 힘든 버그를 만들어낸다...
-> 실행결과를 예측하기가 너무 어려워진다.
-> 인터페이스가 복잡해질수도 있지만 예측할 수 없는 버그로 주말을 반납하는 것 보다는 낫다.
[원칙의 함정]
- 설계는 트레이드 오프의 산물이라는 것이고, 원칙을 맹목적으로 추구하려는 것은 일관성을 잃어버릴 수 있다.
1. 디미터 법칙은 하나의 도트(.) 를 강제하는 규칙이 아니다!
- 다미터 법칙은 결합도와 관련된 것이며, 객체 내부의 구조를 외부로 노출하지 않는다면 문제가 되지 않는다.
ex) Java8 Stream
2. 결합도와 응집도의 충돌
- 클래스는 하나의 변경 원인만을 가져야한다. 서로 상관없는 책임이 뭉쳐있는 클래스는 응집도가 낮으며 작은 변경으 로도 쉽게 무너질 수 있다.
- 디미터 법칙, 묻지 말고 시켜라 원칙을 무작정 따르면 애플리케이션은 응집도가 늦은 객체로 넘쳐날 수 있다!
-> 객체가 본질적으로 책임져야 하는 책임들에 대해서 우선적으로 생각하고! 그 후에 법칙들을 적용하자!
'아키텍처 > OOP' 카테고리의 다른 글
[오브젝트] Chapter8 의존성 관리하기 (2) | 2022.11.04 |
---|---|
[오브젝트] Chapter7 객체 분해 (0) | 2022.11.03 |
[오브젝트] Chapter5 책임 할당하기 (0) | 2022.11.02 |
[오브젝트] Chapter4 설계 품질과 트레이드 오프 (0) | 2022.11.02 |
[오브젝트] Chapter3 역할, 책임, 협력 (0) | 2022.11.02 |