4장에서는 1~3장까지 책에서 이야기해온 책임주도 설계가 가지는 특징들을 응집도와 결합도를 위주로 설명한 장이였습니다. 특히 1~3장에서는 책임 주도 설계 방식으로 구현하는 방법및 장점들을 위주로 설명했지만 4자에서는 설계를 할 때 객체가 가지는 데이터를 중심으로 설계 했을때 생기는 단점에 대해 언급하며 이야기를 풀어나갔습니다.
객체지향 설계란 올바른 객체에게 올바른 책임을 할당하면서 낮은 결합도와 높은 응집도를 가진 구조를 창조하는 활동이다.
객체지향 설계를 "결합도"와 "응집도"를 바탕으로 설명하는 글입니다.
결합도와 응집도를 합리적인 수준으로 유지할 수 있는 중요한 원칙이 있다. 객체의 상태가 아니라 객체의 행동에 초점을 맞추는 것이다.
이전 장에서 계속 이야기한 내용입니다. 포스팅을 하며 문득 든 생각이지만 비슷한 내용을 반복해서 언급하고 있어 공부하기로는 최고인듯 합니다. 다시 책의 내용으로 돌아오면 책에서는 "상태"에 초점을 맞춰 설계를 한 코드와 "행동"에 초점을 맞추어 설계를 한 코드를 서로 비교하며 행동에 초점을 맞추어야 한다고 설명하고 있습니다.
객체의 책임은 인터페이스에 속한다. 객체는 책임을 드러내는 안정적인 인터페이스 뒤로 책임을 수행하는데 필요한 상태를 캡슐화함으로써 구현 변경에 대한 파장이 외부로 퍼져나가는 것을 방지한다. 따라서 책임에 초점을 맞추면 상대적으로 변경에 안정적인 설계를 얻을 수 있게 된다.
인터페이스가 중요한 이유를 다시 한번 더 이야기를 하고 있습니다. 개인적으로는 인터페이스를 먼저 구현하고 내부 로직은 외부에서 접근하지 못하게 접근제어자를 설정하여 로직을 구현하면 변경에 대한 영향을 최소화할 수 있으리라 생각듭니다.
변경될 가능성이 높은 부분을 구현이라고 부르고 상대적으로 안정적인 부분을 인터페이스라고 부른다.
개인적으로는 인터페이스와 그 외라고 부르고 싶습니다. 또한 인터페이스와 구현을 "변경"의 측면에서 이야기를 한 것이라 생각합니다.. 인터페이스가 변경에 상대적으로 안정적으로 만들려면 세부적인 내용대신 추상적인 내용을 인터페이스에 담으면 된다 생각합니다.
캡슐화란 변경 가능성이 높은 부분을 객체 내부로 숨기는 추상화 기법이다. 객체 내부에 무엇을 캡슐화해야 하는가? 변경될 수 있는 어떤 것이라도 캡슐화해야 한다. 이것이 바로 객체지향 설계의 핵심이다.
바로 위에서 작성한 내용과 비슷한 내용이라 생각합니다. 즉 변경가능한 모든것은 캡슐화의 대상이며 캡슐화를 할 때에는 추상적으로 해야 변경에 안정적이라 생각합니다.
응집도는 모듈에 포함된 내부 요소들이 연관돼 있는 정도를 나타낸다.
...
응집도란 변경이 발생할 때 모듈 내부에서 발생하는 변경의 정도로 측정할 수 있다.
첫번째 문장은 일반적인 응집도의 정의이며 두번째 문장은 설계의 관점에서 바라본 응집도라 생각합니다. 그리고 두번째 문장에서 응집도에 대해 구체적으로 언급해주었기에 개념을 잡기 수월했습니다.
결합도는 의존성의 정도를 나타내며 다른 모듈에 대해 얼마나 많은 시직을 갖고 있는지를 나타내는 척도다.
...
결합도는 한 모듈이 변경되기 위해서 다른 모듈의 변경을 요구하는 정도로 측정할 수 있다.
응집도와 마찬가지로 첫번째 문장은 결합도의 일반적인 문장에 대해 설명합니다. 또한 두번째 문장은 설계의 관점에서 바라본 결합도입니다.
좋은 설계란 오늘의 기능을 수행하면서 내일의 변경을 수용할 수 있는 설계다. 그리고 좋은 설계를 만들기 위해서는높은 응집도와 낮은 결합도를 추구해야 한다. 좋은 설계가 변경과 관련된 것이고 응집도와 결합도의 정도가 설계의 품질을 결정한다면 자연스럽게 다음과 같은 결론에 도달하게 된다. 응집도와 결합도는 변경과 관련된 것이다.
그 동안 저는 좋은 설계 == 유지보수하기 편한 설계 라고 생각을 하였습니다. 이는 어느정도 맞는 말이지만 너무 디테일한 설명이라는 생각을 하였습니다. 그렇기에 책에서 짚어준 내용이 이런 저에게 있어 매우 유용했습니다.
앨런 홀럽은 이처럼 접근자와 수정자에 과도하게 의존하는 설계 방식을 추측에 의한 설계 전략이라고 부른다.
이름은 까먹었지만.. 필요한 상황이 다가왔을때에만 구현하는, 클린코드를 구현하는 하나의 방법과도 유사하다고 생각했습니다.
낮은 응집도는 두 가지 측면에서 설계에 문제를 일으킨다.
1. 변경의 이유가 서로 다른 코드들을 하나의 모듈 안에 뭉쳐놓았기 때문에 아무 상관이 없는 코드들이 영향을 받게 된다.
2. 하나의 요구사항 변경을 반영하기 위해 동시에 여러 모듈을 수정해야 한다.
막연하게 낮은 응집도는 안좋다.. 라고만 생각하였던 저에게 있어 구체적인 예시와 함께 설명하였기에 충분히 뜻깊은 내용이라 생각합니다. 저만의 시야로 해당 대목을 재해석한다면 낮은 응집도를 가질 경우 변경시 생각치도 못한 사이드 이펙트가 생기기 때문이라 생각합니다.
캡슐화 위반시 생기는 문제점
1. "코드 중복"이 발생할 확률이 높다는 것이다.
2. "변경"에 취약하다.
캡슐화를 하지 않았다는 말은 단순히 이야기하면 외부에 객체의 상태를 공개했다는 것으로 생각됩니다. 그리고 만약 캡슐화가 되지 못한 정보들을 가지고 특정 로직을 구현해야하며 해당 로직을 여러 군데에서 필요할 경우 동일한 코드가 중복될 수 밖에 없다는 말입니다. 그리고 이렇게 코드를 구현할 경우 중복된 코드의 로직을 수정해야 할 경우 모든 중복된 코드를 일일히 수정해야 하기 때문에 변경에 취약하다는 말이 됩니다.
객체 내부에 저장되는 데이터보다 객체가 협력에 참여하면서 수행할 책임을 정의하는 오퍼레이션이 더 중요하다.
이는 4장 초반에 언급한 데이터중심의 설계보다 책임 중심의 설계가 더 중요하다는 말과 동일하다 생각합니다.
데이터 중심의 설계가 변경에 취약한 이유는 두 가지다.
- 데이터 중심의 설계는 본질적으로 너무 이른 시기에 데이터에 관해 결정하도록 강요한다.
- 데이터 중심의 설계에서는 협력이라는 문맥을 고려하지 않고 객체를 고립시킨 채 오퍼레이션을 결정한다.
데이터 중심의 설계가 가지는 단점을 언급합니다. 이는 평소 행동보다 상태(데이터)를 우선하여 생각하고 객체보다 클래스를 먼저 생각한 저에게 있어 다시금 생각하게 만든 코드중 하나입니다.
'책 > 오브젝트 (완)' 카테고리의 다른 글
06 메시지와 인터페이스 (1) | 2024.01.23 |
---|---|
5장 책임 할당하기 (0) | 2024.01.17 |
3장 역할, 책임, 협력 (1) | 2024.01.15 |
2장 객체 지향 프로그래밍 (0) | 2024.01.11 |
1장 객체, 설계 (0) | 2023.12.28 |