Chapter 1. 객체, 설계

챕터의 초반에 소프트웨어 모듈에 대해 이야기한다.

  1. 실행 중에 제대로 동작하는 것
  2. 변경을 위해 존재하는 것
  3. 코드를 읽는 사람과 의사소통하는 것

그리고 위에 있는 주제를 가지고 예제를 들어 이야기한다.

변경에 취약한 코드

객체 사이의 의존성에 관련된 문제, 물론 의존성을 완전히 없애는 것이 아니라 의존성을 낮추며 협력하는 객체들의 공동체를 만드는 것이 좋다.

이렇게 객체들 간의 의존성이 과한 경우 결합도가 높다고 한다.

이 결합도가 높을 경우 코드 변경에 있어 어려움을 겪을 수가 있다.

그러므로 객체 사이의 결합도를 낮추는 것이 좋다.

그렇기 때문에 설계의 목표는 객체 간의 결합도를 낮춰 코드 수정에 있어 용이한 설계를 만드는 것이다.

의존성이 높은 코드는 코드를 수정하는 데 있어 어려움을 겪을 수 있다.

그럼 어떻게 해야 할까? 객체 하나하나를 더 자유롭게 행동할 수 있도록 만드는 것이다.

자율성

객체 내부에 캡슐화를 사용해자율성을 부여해 주는 것이다. (캡슐화를 통해 객체 내부 접근을 제한한다면 결합도를 낮추며 설계를 좀 더 쉽게 변경할 수 있음.)

이렇게 되면 좀 더 수정하기 쉬운 객체가 될 수 있다.

객체에 자율성을 부여하게 되면 의존도가 낮아지게 됨으로 객체 스스로가 문제에 책임을 질 수 있게 된다. (외부로 노출된 기능이 아니기에 내부에서 해결할 수 있어 코드 변경에 있어 유리하다.)

캡슐화와 응집도

객체 내부의 상태를 캡슐화하고 메시지를 통해 상호작용하도록 만들게 되면 객체 간의 원하는 결과 만을 반환할 것을 알고 있다.

이렇게 객체 간의 연관된 작업만을 수행하고 연관이 없는 작업은 다른 객체에게 위임하는 객체를 응집도가 높다 한다.

자신의 데이터를 스스로 처리하는 자율적인 객체는 결합도를 낮추고 응집도를 높인다.

하지만 응집도를 높이기 위해서는 스스로 자신의 데이터를 책임져야 하기 때문에 자신의 데이터는 자기 스스로 처리할 줄 알아야 한다.

이렇게 외부의 간섭을 배제하고 메시지를 통해 협력하는 자율적인 객체들의 공동체를 만드는 것이 훌륭한 객체지향 설계를 얻을 수 있는 것이다.

절차 지향과 객체지향

프로세스와 데이터를 별도의 모듈에 위치시키는 방식을 절차적 프로그래밍이라고 한다.

절차 지향 프로그래밍에서는 객체들이 수동적이 존재들이다.

때문에 절차 지향 프로그래밍은 프로세스가 필요한 모든 데이터에 의존해야 하는 근본적인 문제점 때문에 코드의 변경에 취약할 수밖에 없다.

이러한 문제점을 해결하기 위해서는 자신의 데이터는 자기 스스로 처리할 수 있도록 하는 객체지향 프로그래밍이 효율적일 수 있다.

그러기 위해서는 데이터와 프로세스가 동일한 모듈 내부에 위치하도록 하고 캡슐화를 이용한 의존성을 적절히 관리해 객체 사이의 결합도를 낮추는 것이다.

책임의 이동

절차 지향과 객체지향의 근본적인 차이를 만드는 것은 책임의 이동이다. (여기서 책임을 기능을 가리키는 객체지향 세계의 용어로 생각하라 한다.)

객체지향 프로그래밍은 하나의 객체에 과분한 책임은 분산시켜 결합도를 낮추고 코드 변경에 쉽게 대응할 수 있다.

객체지향 설계에서는 하나의 객체가 과분한 책임을 가지고 있지 않고 책임을 분산시켜 객체 스스로가 책임을 진다는 것이다.

이렇게 설계하게 되면 객체지향 애플리케이션은 스스로 책임을 수행하는 자율적인 객체들의 공동체를 구성하게 된다.

객체지향 설계의 핵심은 적절한 객체에 적절한 책임을 할당이고 어떤 책임을 할당할 것인가 가 중요하다.

여기서 설계를 어렵게 만드는 것은 의존성이다.

이것의 해결 방법은 불필요한 의존성을 제거하고 객체 사이의 결합도를 낮추는 것이다.

불필요한 세부사항은 내부로 캡슐화하여 객체의 자율성을 높이며 응집도 높은 객체들의 공동체를 만들 수 있게 한다.

거기에 최소한의 의존성만을 남기는 것이 훌륭한 객체지향 설계이다.

설계가 왜 필요한가

설계와 구현은 떨어트려 이야기할 수 없으며 설계는 코드 작성의 일부이며 코드를 작성하지 않고 검증할 수 없다.

오늘 완성해야 하는 기능을 구현하는 동시에 내일 쉽게 변경할 수 있는 코드를 짜야 한다.

좋은 설계란 오늘 요구하는 기능을 온전히 수행하면서 내일의 변경을 매끄럽게 수용할 수 있는 설계이다.

설계가 중요한 이유는 요구 사항이 항상 변경되기 때문이다.

객체지향 설계

객체지향 프로그래밍은 의존성을 효율적으로 통제할 수 있는 다양한 방법을 제공하여 요구 사항 변경에 좀 더 수월하게 대응할 수 있게 해준다.

객체 역시 자신의 데이터를 스스로 책임지는 자율적인 존재이며 코드를 좀 더 쉽게 이해할 수 있게 해준다.

단순히 데이터와 프로세스를 객체라는 덩어리 안에 넣었다고 해서 변경하기 쉬운 설계가 아니다.

객체들 간의 상호작용을 통해 구현되고 이 상호작용은 객체 사이에 주고받는 메시지로 표현된다.

메시지를 전송하기 위해 이런 지식이 두 객체를 결합시켜 이 결합이 객체 사이의 의존성을 만든다.

훌륭한 객체지향 설계는 협력하는 객체 사이의 의존성을 적정하게 관리하는 설계이다.

객체 간의 의존성은 애플리케이션을 수정하기 어렵게 만드는 주범이다.