일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 디자인패턴
- 안드로이드
- android
- Rxjava
- viewmodel
- 안드로이드스튜디오
- k8s
- 글또
- 병렬프로그래밍
- theming
- 테스트
- ReactiveProgramming
- 커스텀상태
- 코루틴
- 스레드
- 회고
- 자바
- 책
- Gradle
- mockito
- g 단위테스트
- Coroutine
- Compose
- 알고리즘
- 병럴프로그래밍
- Kotlin
- kotlin강좌
- 코틀린
- 알게되는
- 안드로이드강좌
- Today
- Total
선생님, 개발을 잘하고 싶어요.
[오브젝트] 챕터 4 - 설계 품질과 트레이드오프 본문
지금까지는 데이터 중심으로 생각한 것 같습니다. 책임 중심 관점으로 쉬프트를 해볼 가치는 있는 것 같습니다.
근데 객체에게 어느 정도까지 책임을 쪼갤 것이냐 하는 문제가 항상 있습니다.
여기서 저자는 트레이드 오프를 얘기합니다. 책임을 너무 쪼개서 마냥 좋다는 건 아니란 거죠.
그렇다면 어떤 기준을 잡고 쪼개야 할 까요? 이를 우리 스스로 판단할 판단 기준을 알려줍니다.
캡슐화, 응집도, 결합도가 그것입니다.
하지만 이 품질 척도가 절대적으로 지켜저야 하는 건 아니라는 점을 다시 상기하게 됩니다.
이런 척도가 생긴 이유를 항상 상기해야합니다.
변경에 강한 코드를 작성하는 것이 우리의 목적이였습니다.
협력: 기능을 구현하기 위해 메시지를 주고받는 객체간 상호작용
책임: 다른 객체와 협력하기 위해 수행하는 행동
역할: 대체 가능한 책임의 집합
객체지향 설계의 핵심은 책임
책임 할당이 설계 품질과 깊이 연관 (응집도, 결합도)
훌륭한 설계: 합리적인 비용안에서 변경을 수용할 수 있는 구조를 만드는 것
비용을 정확히 아는가?
변경될 곳을 추정할 수 있는가?
<aside> 💡 객체의 행동에 초점을 맞추는 것 부터 시작하자.
</aside>
데이터 중심 관점: 데이터 조작하는데 필요한 오퍼레이터 정의 (서버 입장에서 생각한다)
책임 중심 관점: 인터페이스를 위해 상태를 보관한다. (클라이언트 입장에서 생각한다)
서버 코드를 작성하는데, 클라이언트 입장에서 생각하는 코드가 더 좋은 객체지향 설계를 완성한다는게 재밌네
데이터 중심 관점의 냄새
- “데이터가 무엇인가”로 설계를 시작한다
- 객체의 책임을 결정하기도 전에 “객체가 포함해야하는 데이터가 뭐지?”를 항상 고민한다.
- 데이터 클래스를 조합해서 기능을 수행하는 객체가 있다.
- 너무 이른 시기에 내부 구현에 초점을 맞춘다. (이로 인해 캡슐화에 실패하게 된다.)
품질 척도 (변경의 관점에서 설계의 품질을 판단)
- 캡슐화
- 객체의 내부 구현을 외부로부터 감춤
- 구현: 나중에 변경될 가능성이 높은 것
- 인터페이스: 상대적으로 안정된 부분
- 변경의 정도에 따라 구현과 인터페이스를 분리할 것
- 클라이언트는 서버의 인터페이스에만 의존할 것
- </aside>
- 응집도
- 모듈에 포함된 내부 요소가 연관돼 있는 정도
- e.g 모듈 내 요소들이 하나의 목적을 위해 긴밀하게 협력한다면? → 높은 응집도
- 변경이 발생할 때 모듈 내부에서 발생하는 변경의 정도로 측정할 수 있다.
- e.g 하나의 변경 때문에 모듈 전체가 함께 변경된다면 응집도가 높은 것
- 응집도가 높을수록 변경의 대상과 범위가 명확해진다. → 코드 변경하기 쉬워진다.
- 결합도
- 다른 모듈에 대해 얼마나 많은 지식을 갖고 있는지 나타내는 척도
- e.g 어떤 모듈이 다른 모듈에 대해 꼭 필요한 지식만 알고 있다면? → 낮은 결합도
- 한 모듈이 변경되기 위해서 다른 모듈의 변경을 요구하는 정도로 측정할 수 있다.
- i.e 하나의 모듈을 수정할 때 얼마나 많은 모듈을 함께 수정해야 하는가?
- 결합도가 높을수록 변경해야하는 모듈 수가 늘어난다. → 코드 변경하기 어렵다.
<aside> 💡 변경 관점에서 높은 응집도 그리고 낮은 결합도를 가진 모듈을 설계해야한다.
</aside>
<aside> 💡 캡슐화의 정도가 응집도와 결합도를 결정한다.
</aside>
데이터 중심 설계가 가진 문제점
- 캡슐화 위반
- getter, setter를 사용한다고 캡슐화를 하는게 아니다.
- 무분별한 사용은 인터페이스를 통해서 내부 구현에 대해서 말하는 것
- 설계할 때 협력에 관해 고민하지 않으면 캡슐화를 위반하는 과도한 접근자와 수정자를 가질 위험이 있다.
- 추측에 의한 설계: 협력을 고려하지 않고 객체가 다양한 상황에 사용될 수 있을 것이라는 막연한 추측을 기반으로 설계를 진행
- getter, setter를 사용한다고 캡슐화를 하는게 아니다.
- 높은 결합도
- 데이터 객체를 사용하는 제어 로직이 특정 객체에 집중
- 제어 객체가 다수의 데이터 객체에 강하게 결합
- 낮은 응집도
- 응집도를 확인하기 위해서는 코드를 수정하는 이유를 살펴야한다.
- 서로 다른 이유로 변경되는 코드가 하나의 모듈에 공존한다면 악취다.
- 데이터 중심 설계는 객체의 행동보다 상태에 집중한다.
- 너무 이른 시기에 내부 구현에 초점을 맞춘다.
캡슐화를 지켜라.
- 객체는 자신이 어떤 데이터를 가지고 있는지 외부에 공개하면 안된다.
- 객체에게 의미있는 메서드는 객체의 책임을 수행하는 메서드
- 메서드의 시그니처를 통해서 객체 내부의 상태를 드러내는 경우가 있다. → 부주의한 갭슐화 위반
- 캡슐화는, 변경될 수 있는 어떤 것이라도 감추는 것
<aside> 💡 올바른 객체지향 설계의 무게중심은 객체의 내부가 아니라 외부에 맞춰져야 한다.
</aside>
'일상 > 책 리뷰' 카테고리의 다른 글
[오브젝트] 챕터 6 - 메시지와 인터페이스 (0) | 2022.03.05 |
---|---|
[오브젝트] 챕터 5 - 책임 할당하기 (0) | 2022.03.02 |
[오브젝트] 챕터 3 - 역할, 책임, 협력 (0) | 2022.03.01 |
[오브젝트] 챕터 2 - 객체지향 프로그래밍 (0) | 2022.03.01 |
[오브젝트] 챕터1 - 객체, 설계 (0) | 2022.03.01 |