클래스의 필드나 메서드를 적절히 private, public 으로 설정하므로서 클래스의 내부와 외부를 구분해야한다. 즉, 적절히 클래스의 경계를 구분하는 것이 중요하다. 왜? → 경계의 명확성이 객체의 자율성을 보장하기 때문이다. 경계를 모호하게 해두면 챕터1에서 살펴본 것처럼 god class만이 주도하는 절차지향적인 프로그래밍 방식의 가능성을 열어버리게 된다.

다시 말하지만 설계가 필요한 이유는 변경을 관리하기 위해서라는 것을 기억해야한다. 객체 사이의 의존성을 적절히 관리함으로써 변경에 대한 파급 효과를 제어할 수 있어야한다. 접근제어 역시 이런 기법 중 하나이다. private 접근제어자를 사용함으로써 클라이언트는 세부사항을 모르고 공개 인터페이스만을 이용해 기능을 사용할 수 있고 클래스 서버는 마음껏 내부 구현을 변경할 수 있다라는 장점을 가지게 된다. 또한 변경이 미치는 영향의 정도를 낮출 수 있다. → 인터페이스와 구현의 분리 원칙

코드의 의존성과 실행 시점의 의존성은 서로 다를 수 있다. 그리고 이를 통해 유연하고 쉽게 재사용 가능한 구조를 만들어 낼 수 있다. → 근데 사실 이건 코드 이해를 어렵게 만드는 요인 중 하나이다. 실제 코드의 의존성과 실행 시점 의존성이 다르면 코드를 이해하기 위해 객체를 생성하고 연결하는 부분을 찾아야하기 때문이다. 그 대신 유연해지고 확장성이 높아진다는 장점을 가질 수 있게 된다. 트레이드 오프인 것이지.

상속

클래스를 하나 추가하고 싶은데 기존 클래스와 매우 유사하다고 가정해보자. 그렇다면 중복된 코드를 쓰지 않기 위해 기존 클래스의 내용을 그대로 가져오고 싶은 니즈가 생기는데 이 때 활용할 수 있는 것이 바로 상속이다. 상속을 사용하면 기존 클래스가 가지고 있던 모든 필드와 메서드를 물려받을 수 있다.

이러면 재사용의 측면에서만 상속의 장점이 드러나는데 사실 상속의 가장 핵심은 부모 클래스의 인터페이스를 물려받는 다는 것이다. → 부모가 이해할 수 있는 메시지는 자식 클래스도 이해할 수 있다 → 클라이언트 객체는 부모나 자식이나 동일한 타입으로 간주할 수 있다. → 다형성!

클라이언트가 동일한 메시지를 전송하지만 실제로 어떤 메서드가 실행될 것인지는 메시지를 수신하는 객체의 클래스가 무엇이냐에 따라 달라지는 것을 다형성이라고 한다. 다형성은 객체지향 프로그램의 컴파일 타임 의존성과 런타임 의존성이 다를 수 있다는 사실을 기반으로 한다.

상속보다 합성을 선호하는 이유

우선 합성은 다른 객체의 인스턴스를 자신의 인스턴스 변수로 포함해서 재사용하는 방법이다.

상속은 객체지양에서 코드를 재사용하기 위해 널리 사용되는 기법이다. 하지만 두 가지 관점에서 설계에 안좋은 영향을 미친다.

  1. 캡슐화를 위반한다.