선생님, 개발을 잘하고 싶어요.

[오브젝트] 챕터 4 - 설계 품질과 트레이드오프 본문

일상/책 리뷰

[오브젝트] 챕터 4 - 설계 품질과 트레이드오프

알고싶은 승민 2022. 3. 1. 23:30

지금까지는 데이터 중심으로 생각한 것 같습니다. 책임 중심 관점으로 쉬프트를 해볼 가치는 있는 것 같습니다.

근데 객체에게 어느 정도까지 책임을 쪼갤 것이냐 하는 문제가 항상 있습니다.

여기서 저자는 트레이드 오프를 얘기합니다. 책임을 너무 쪼개서 마냥 좋다는 건 아니란 거죠.

그렇다면 어떤 기준을 잡고 쪼개야 할 까요? 이를 우리 스스로 판단할 판단 기준을 알려줍니다.

캡슐화, 응집도, 결합도가 그것입니다.

 

하지만 이 품질 척도가 절대적으로 지켜저야 하는 건 아니라는 점을 다시 상기하게 됩니다.

이런 척도가 생긴 이유를 항상 상기해야합니다.

변경에 강한 코드를 작성하는 것이 우리의 목적이였습니다.


협력: 기능을 구현하기 위해 메시지를 주고받는 객체간 상호작용

책임: 다른 객체와 협력하기 위해 수행하는 행동

역할: 대체 가능한 책임의 집합

객체지향 설계의 핵심은 책임

책임 할당이 설계 품질과 깊이 연관 (응집도, 결합도)

훌륭한 설계: 합리적인 비용안에서 변경을 수용할 수 있는 구조를 만드는 것

비용을 정확히 아는가?

변경될 곳을 추정할 수 있는가?

<aside> 💡 객체의 행동에 초점을 맞추는 것 부터 시작하자.

</aside>

데이터 중심 관점: 데이터 조작하는데 필요한 오퍼레이터 정의 (서버 입장에서 생각한다)

책임 중심 관점: 인터페이스를 위해 상태를 보관한다. (클라이언트 입장에서 생각한다)

서버 코드를 작성하는데, 클라이언트 입장에서 생각하는 코드가 더 좋은 객체지향 설계를 완성한다는게 재밌네

데이터 중심 관점의 냄새

  • “데이터가 무엇인가”로 설계를 시작한다
  • 객체의 책임을 결정하기도 전에 “객체가 포함해야하는 데이터가 뭐지?”를 항상 고민한다.
  • 데이터 클래스를 조합해서 기능을 수행하는 객체가 있다.
  • 너무 이른 시기에 내부 구현에 초점을 맞춘다. (이로 인해 캡슐화에 실패하게 된다.)

품질 척도 (변경의 관점에서 설계의 품질을 판단)

  • 캡슐화
    • 객체의 내부 구현을 외부로부터 감춤
    • 구현: 나중에 변경될 가능성이 높은 것
    • 인터페이스: 상대적으로 안정된 부분
      • 변경의 정도에 따라 구현과 인터페이스를 분리할 것
      • 클라이언트는 서버의 인터페이스에만 의존할 것
    <aside> 💡 객체지향 프로그래밍의 장점은 오직 캡슐화를 목표로 인식할 때만 달성될 수 있다.
  • </aside>
  • 응집도
    • 모듈에 포함된 내부 요소가 연관돼 있는 정도
    • e.g 모듈 내 요소들이 하나의 목적을 위해 긴밀하게 협력한다면? → 높은 응집도
    • 변경이 발생할 때 모듈 내부에서 발생하는 변경의 정도로 측정할 수 있다.
    • e.g 하나의 변경 때문에 모듈 전체가 함께 변경된다면 응집도가 높은 것
    • 응집도가 높을수록 변경의 대상과 범위가 명확해진다. → 코드 변경하기 쉬워진다.
  • 결합도
    • 다른 모듈에 대해 얼마나 많은 지식을 갖고 있는지 나타내는 척도
    • e.g 어떤 모듈이 다른 모듈에 대해 꼭 필요한 지식만 알고 있다면? → 낮은 결합도
    • 한 모듈이 변경되기 위해서 다른 모듈의 변경을 요구하는 정도로 측정할 수 있다.
    • i.e 하나의 모듈을 수정할 때 얼마나 많은 모듈을 함께 수정해야 하는가?
    • 결합도가 높을수록 변경해야하는 모듈 수가 늘어난다. → 코드 변경하기 어렵다.

<aside> 💡 변경 관점에서 높은 응집도 그리고 낮은 결합도를 가진 모듈을 설계해야한다.

</aside>

<aside> 💡 캡슐화의 정도가 응집도와 결합도를 결정한다.

</aside>

데이터 중심 설계가 가진 문제점

  • 캡슐화 위반
    • getter, setter를 사용한다고 캡슐화를 하는게 아니다.
      • 무분별한 사용은 인터페이스를 통해서 내부 구현에 대해서 말하는 것
    • 설계할 때 협력에 관해 고민하지 않으면 캡슐화를 위반하는 과도한 접근자와 수정자를 가질 위험이 있다.
    • 추측에 의한 설계: 협력을 고려하지 않고 객체가 다양한 상황에 사용될 수 있을 것이라는 막연한 추측을 기반으로 설계를 진행
  • 높은 결합도
    • 데이터 객체를 사용하는 제어 로직이 특정 객체에 집중
    • 제어 객체가 다수의 데이터 객체에 강하게 결합
  • 낮은 응집도
    • 응집도를 확인하기 위해서는 코드를 수정하는 이유를 살펴야한다.
    • 서로 다른 이유로 변경되는 코드가 하나의 모듈에 공존한다면 악취다.
  • 데이터 중심 설계는 객체의 행동보다 상태에 집중한다.
    • 너무 이른 시기에 내부 구현에 초점을 맞춘다.

캡슐화를 지켜라.

  • 객체는 자신이 어떤 데이터를 가지고 있는지 외부에 공개하면 안된다.
  • 객체에게 의미있는 메서드는 객체의 책임을 수행하는 메서드
  • 메서드의 시그니처를 통해서 객체 내부의 상태를 드러내는 경우가 있다. → 부주의한 갭슐화 위반
    • 캡슐화는, 변경될 수 있는 어떤 것이라도 감추는 것

<aside> 💡 올바른 객체지향 설계의 무게중심은 객체의 내부가 아니라 외부에 맞춰져야 한다.

</aside>

Comments