본문 바로가기

공부기록/객체지향

오브젝트 4장 - 설계 품질과 트레이드 오프

올바른 객체에게 올바른 책임을 할당하면서 낮은 결합도와 높은 응집도를 가진 구조를 창조하는 활동, 객체지향 설계의 핵심이 책임. 책임을 할당하는 작업이 응집도와 결합도 같은 설계 품질과 깊이 연관돼 있다는 것

변경 →비용

훌륭한 설계 → 변경에 드는 비용이 합리적인 선에서 되도록

적절한 비용 안에서쉽게 변경할 수 있는 설계는 응집도가 높고 서로 느슨하게 결합돼 있는 요소로 구성된다.

나쁜 설계와 좋은 설계를 비교하면서 살펴볼 때 효과가 좋다.

책임이 아닌 상태를 표현하는 데이터 중심의 설계를 살펴보고 객체지향적으로 설계한 구조와 어떤 차이점이 있는지 살펴본다.

상태를 분할의 중심축으로 삼는 방법

책임을 분할의 중식축으로 삼는 방법

책임에 맞추면 변경하기 쉽다. 책임은 인터페이스에 속한다.

상태를 객체 분할의 중심축으로 삼으면 구현에 관한 세부사항이 객체의 인터페이스에 스며들게 되어 캡슐화의 원칙이 무너진다.

데이터 중심의 설계 → 객체가 포함해야 하는 데이터에 집중한다.

설계 트레이드오프

캡슐화, 응집도, 결합도

→ 상태와 행동을 하나로 모으는 것은 객체의 내부 구현을 외부로부터 감추기 위해서다.

변경될 가능성이 높은 부분 = 구현, 상대적으로 안정적인 부분 = 인터페이스

캡슐화 → 시스템의 한 부분을 감춤으로 뜻밖의 피해가 발생할 수 있는 가능성을 사전에 방지할 수 있따.

응집도

모듈에 포함된 내부 요소들이 연관돼 있는 정도. 모듈 내의 요소들이 하나의 목적을 위해 긴밀하게 협력한다면 높은 응집도를 지님. 관련 높은 책임을 할당할 수록 → 응집도 상승

변경이 발생할 때 모듈 내부에서 발생하는 변경의 정도. → 모듈 외부에서 변경이 발생(응집도가 낮음)

응집도가 높을수록 변경의 대상과 범위가 명확해짐

결합도

다른 모듈에 대해 얼마나 많은 지식을 갖고 있는지

→적절한 수준의 관계만을 유지해야함

한 모듈이 변경되기 위해서 다른 모듈의 변경을 요구하는 정도 → 하나의 모듈을 수정할 때, 얼마나 많은 모듈을 함께 수정해야하는가

→ 내부 구현을 변경했을 때, 다른 모듈에 영향을 미치는 경우에는 결합도가 높고, 퍼블릭 인터페이스를 수정했을 때만 다른 모듈에 영향을 미치는 경우에는 결합도가 낮다. →따라서 클래스는 구현이 아닌 인터페이스에 의존하도록 코드를 작성해야 낮은 결합도를 얻을 수 있다.

(인터페이스에 대해 프로그래밍하라(GOF94))

String이나 ArrayList는 변경될 확률이 매우 낮기 때문에, 변경될 확률이 매우 적은 안정적인 모듈에 의존하는 것은 아무런 문제가 되지 않는다.

좋은 설계: 높은 응집도와 낮은 결합도

→ 이런 이야기를 한 이유

데이터 중심의 설계는 응집도가 낮고 결합도가 높다(캡슐화 위반, 객체 내부의 구현을 인터페이스로 만듬)

객체지향의 설계는 응집도가 높고 결합도가 낮다( 인터페이스만 보임)

협력에 관해 고민하지않으면 과도한 접근자와 수정자를 가지게 되는 경향이 있다.

접근자와 수정자에 과도하게 의존하는 설계 방식을 추측에 의한 설계 저략이라고 부른다.

사용될 수 있을 것이라는 막연한 추측을 기반으로 설계를 진행한 결과물

높은 결합도 →객체의 내부 구현을 변경했음에도 이 인터페이스에 의존하는 하는 모든 클라이언트들도 함께 변경해야한다는 것

서로 다른 이유로 수정하게 되면 →골치아픔 ㅠ

하나의 이유만으로 수정하게 해야한다(SRP) → 이것은 결국, 높은 응집도를 가진다는 말이었구나..

낮은 응집도가 가지는 문제

→변경의 이유가 서로 다른 코드들을 하나의 모듈 안에 뭉쳐놓았기 때문에 변경과 아무 상관이 없는 코드들이 영향을 받게 된다.

→ 하나의 요구사항 변경을 반영하기 위해 동시에 여러 모듈을 수정해야 한다.

자율적인 객체를 향해

캡슐화는 설계의 제1원리

데이터 중심의 설계가 낮은 응집도와 높은 결합도라는 문제로 모살을 앓게 된 근본적인 원인은 캡슐화의 원칙을 위반했기 때문

스스로 자신의 데이터를 책임지는 객체

→객체가 어떤 데이터를 포함해야 하는가

→ 객체가 데이터에 대해 수행해야 하는 오퍼레이션은 무엇인가

캡슐화의 진정한 의미

→ 변경될 수 있는 어떤 것이라도 감추는 것

내부 구현 변경으로 인해 외부의 객체가 영향을 받는다면 캡슐화를 위반한 것이다 .

데이터 중심 설계의 문제점

캡슐화 위반. 높은 응집도와 낮은 결합도를 가질 확률은 극히 낮음

→ 따라서 캡슐화를 위반한 설계는 변경에 취약할 수 밖에 없음

너무 이른 시기에 데이터에 관해 결정하도록 강요한다

협력이라는 문맥을 고려하지 않고 객체를 고립시킨 채 오퍼레이션을 결정한다

객체의 행동보다는 상태에 초점을 맞춤

→ 시작할때, 이 객체에 필요한 데이터는 무엇인가? 고민하여 그것부터 채움

→ 데이터는 세부사항(구현)

데이터의 관점에서 객체는 단순한 데이터의 집합체일 뿐

데이터 중심의 설계는 객체를 고립시킨 채 오퍼레이션을 정의하도록 만든다

객체지향 애플리케이션은 협력하는 객체들의 공동체지만,

객체를 데이터 묶음으로 보면, 다른 객체와 협력하지 않고, 그냥 프로세스에게 쓰임당함

중요한 것은 객체와 다른 객체가 협력하는 방법

데이터 중심의 설계의 초점은 객체의 외부가 아닌 내부로 향함.

→ 객체의 인터페이스에 구현이 노출돼 있었기 때문에 협력이 구현 세부사항에 종속돼 있고, 그에 따라 객체 내부의 구현이 변경됐을 떄 협력하는 객체 모두가 영향을 받을 수밖에 없었던 것이다

 

설계 트레이드 오프? 응집도가 높고 결합도가 낮으면 좋은 것으로 보이는데..

오히려 이전장에서 트레이드 오프를 설명했던 것 같다