조영호의 '오브젝트'를 읽고 알게 된 내용을 정리한다 😊
4장. 설계 품질과 트레이드오프
🌈 TIL
- 객체지향설계는 올바른 객체에게 올바른 책임을 할당하는 것이다. 이를 통해 낮은 결합도와 높은 응집도를 가진 구조를 만들 수 있다.
- 응집도는 모듈에 포함된 내부 요소들이 연관되어있는 정도다.
- 결합도는 의존성의 정도다.
- 캡슐화를 지키면 응집도는 높아지며 결합도는 낮아진다.
- 데이터 중심의 설계는 캡슐화 위반, 높은 결합도, 낮은 응집도의 문제가 있을 가능성이 높다.
- 접근자와 수정자 메서드를 사용하는 게 캡슐화를 한다고 생각했는데 아니라는 것을 알았다. 속성의 가시성을 private로 설정했다고 해도 접근자와 수정자를 통해 속성을 외부로 제공하면 캡슐화를 위반한 것이다.
- 추측에 의한 설계전략(design-by-guessing strategy)는 접근자와 수정자에 과도하게 의존하는 설계다.
5장. 책임 할당하기
🌈 TIL
- 메시지를 전송하는 쪽의 의도에 맞게 책임을 할당해야 한다.
- GRASP는 General Responsibility Assignment Software Pattern이다. 객체에게 책임을 할당할 때 지침으로 삼을 수 있는 원칙들의 집합을 패턴으로 정리한 것이다.
- INFORMATION EXPERT는 정보 정문가 패턴이다. 책임을 수행할 정보를 알고 있는 객체에게 책임을 할당해야한다.
- LOW COUPLING은 낮은 결합도 패턴이다.
- HIGH COHESION은 높은 응집도 패턴이다.
- LOW COUPLING과 HIGH COHESION는설계를 진행하면서 책임과 협력의 품질을 검토하는데 사용할 수 있는 중요한 평가 기준이 된다.
- CREATOR는 창조자 패턴이다. 객체를 생성할 책임을 어떤 객체에게 할당할지에 대한 지침을 제공한다. 아래 조건을 많이 충족하는 객체가 무엇일지 생각해보면 좋다.
- B가 A 객체를 포함하거나 참초
- B가 A 객체를 기록
- B가 A 객체를 긴밀하게 사용
- B가 A 객체를 초기화하는 데 필요한 데이터를 가지고 있다.
- 클래스의 응집도 판단 기준
- 클래스가 하나 이상의 이유로 변경돼야 한다면 응집도가 낮다.
- 클래스의 인스턴스를 초기화하는 시점에 경우에 따라 서로 다른 속성들을 초기화하고 있다면 응집도가 낮다.
- 메서드 그룹이 속성 그룹을 사용하는지 여부로 나뉜다면 응집도가 낮다.
- POLYMORPHISM은 다형성 패턴이다. 객체의 타입에 따라 변하는 행동이 있다면 타입을 분리하고 변화하는 행동을 각 타입의 책임으로 할당
- PROTECTED VARIATIONS는 변경 보호 패턴이다. 예를 들어, A 클래스를 수정하지 않아도 오직 B 인터페이스를 실체화하는 클래스를 추가하는 경우
- Refactoring은 이해하기 쉽고 수정하기 쉬운 소프트웨어로 개선하기 위해 겉으로 보이는 동작은 바꾸지 않은 채 내부 구조만 변경하는 것이다.
- monster method는 응집도가 낮기 때문에 재사용, 변경하기가 어려운 긴 메서드다. 메서드를 작게 분해해서 메서드의 응집도를 높일 수 있다.
- 메서드를 다른 클래스로 이동시킬 때 일반적으로 인자에 정의된 클래스 중 하나로 이동한다.
6장. 메시지와 인터페이스
- Client-Server 모델
- 협력 안에서 메시지를 전송하는 객체는 Client
- 메시지를 수신하는 객체가 Server
- 메시지는 객체들이 협력하기 위해 사용할 수 있는 유일한 의사소통 수단 ex) 메시지수신자. 오퍼레이션명(인자)
- 메시지 전송 / 메시지 패싱은 한 객체가 다른 객체에게 도움을 요청하는 것
- 메시지 전송자는 메시지를 전송하는 객체
- 메시지 수신자는 메시지를 수신하는 객체
- 클래스 의존성은 Association, Dependency, Inheritance, Realization이 있다.
- 양방향 의존성은 피하자.
- Many to One처럼 다중성이 적은 방향을 선택하자.
- 패키지 사이의 의존성 사이클을 제거하자.
- 메서드는 메시지를 수신했을 때 실제로 실행되는 함수 또는 프로시저이며 오퍼레이션의 구현
- 오퍼레이션은 프로그래밍 언어의 관점에서 퍼플릭 인터페이스에 포함된 메시지. 추상적이다. 동일한 오퍼레이션이라도 메서드는 다를 수 있다.
- 퍼블릭 인터페이스는 객체가 의사소통을 위해 외부에 공개하는 메시지의 집합
- 시그니처(signature)는 오퍼레이션 또는 메서드의 이름과 파라미터의 목록을 합친 것
- 좋은 인터페이스는 최소한의 인터페이스와 추상적인 인터페이스라는 조건을 만족해야 한다.
- 퍼블릭 인터페이스의 품질에 영향을 미치는 원칙
- 디미터 법칙
- 클래스가 특정한 조건을 만족하는 대상에게만 메시지를 전송
- ex) this 객체, 메서드의 매개변수, this의 속성, this의 속성인 컬렉션의 요소, 메서드 내에서 생성된 지역 객체
- screening.getMovie().getDiscountConditions();와 같은 코드는 디미터 법칙을 위반
- IntStream.of(1, 15, 20, 3, 9).filter(x -> x > 10).distinct().count();와 같은 코드는 디미터 법칙을 지킴. 객체 내부의 구현에 대한 어떤 정보도 외부로 노출하지 않았다.
- 묻지 말고 시켜라
- 의도를 드러내는 인터페이스
- 클라이언트 관점에서 isSatisfiedByPeriod, isSatisfiedBySequence와 같은 메서드명은 할인조건을 판단하는 동일한 작업을 실행한다. 내부 구현을 이해하지 못 하면 동일한 작업을 수행한다는 것을 알지 못 한다. 이처럼 책임을 수행하는 방법을 드러내는 메서드를 사용한 설계는 변경에 취약함
- 명령과 쿼리 분리 원칙(Command-Query Separation 원칙)
- routine는 어떤 절차를 묶어 호출이 가능하도록 이름을 부여한 기능 모듈
- Procedure는 정해진 절차에 따라 내부의 상태를 변경하는 루틴의 한 종류
- 부수효과를 발생시킬 수 있지만 값을 반환할 수 없다.
- Function은 어떤 절차에 따라 필요한 값을 계산해서 반환하는 루틴의 한 종류
- 값을 반환할 수 있지만 부수효과를 발생시킬 수 없다.
- 명령은 객체의 상태를 수정하는 오퍼레이션이고, 프로시저다.
- 객체의 상태를 변경하는 명령은 반환값을 가질 수 없다.
- 쿼리는 객체와 관련된 정보를 반환하는 오퍼레이션이고, 함수다.
- 객체의 정보를 반환하는 쿼리는 상태를 변경할 수 없다.
- Command-Query Interface는 명령-쿼리 분리 원칙에 따라 작성된 객체의 인터페이스다.
- 디미터 법칙
반응형
'JAVA' 카테고리의 다른 글
Factory Pattern을 적용한 리팩토링 (0) | 2024.09.03 |
---|---|
이상한 나라의 객체 | 역할, 책임, 협력 (0) | 2024.07.15 |
Facade Pattern (0) | 2024.07.03 |
HttpURLConnection | RestTemplate | WebClient (0) | 2023.12.28 |
enums(열거형) (0) | 2023.05.22 |