[오브젝트] 8장 의존성 관리하기
[오브젝트] 8장 의존성 관리하기

[오브젝트] 8장 의존성 관리하기

Tags
조영호
OOP
Java
Published
September 1, 2023
Author
lkdcode

의존성 관리하기

객체지향 설계의 핵심은 협력을 위해 필요한 의존성은 유지하며너도 변경을 방해하는 의존성은 제거하는 것

변경과 의존성

의존성은 방향성을 가지며 항상 단방향이다.
  • 실행 시점 : 의존하는 객체가 정상적으로 동작하기 위해서는 실행 시에 의존 대상 객체가 반드시 존재해야 한다.
  • 구현 시점 : 의존 대상 객체가 변경될 경우 의존하는 객체도 함께 변경된다.
의존성은 변경에 의한 영향의 진짜 가능성을 암시한다.
🤔

의존성 전이

추상화한 객체의 의존할 경우 구현체에 대해서도 자동적으로 의존하게 되는 것이다. 의존성이란 의존하고 있는 대상의 변경에 영향을 받을 수 있는 가능성이다.
  • 런타임 의존성 : 실행되고 나서 구현체에 의존되는 결합도를 일컫는다
  • 컴파일 의존성 : 컴파일 시점에 의존되는 결합도를 일컫는다
🤔

컨텍스트 독립성

클래스가 특정한 문맥에 강하게 결합될수록 다른 문맥에서 사용하기는 더 어려워진다. 클래스가 사용될 특정한 문맥에 대해 최소한의 가정만으로 이뤄져 있다면 다른 문맥에서 재사용하기가 더 수월해진다. 이를 컨텍스트 독립성이라고 부른다.
객체가 해당 객체를 실행하는 시스템에 관해 아무것도 알지 못한다는 의미다.

의존성 해결하기

컴파일 타임 의존성을 실행 컨텍스트에 맞는 적절한 런타임 의존성으로 교체하는 것을 의존성 해결이라 부른다.
  • 생성자를 통한 해결
  • setter 메서드를 통한 해결
  • 메서드 인자를 이용한 해결
ex) Movie 가 항상 할인 정책을 알 필요까지는 없고 가격을 계산할 때만 일시적으로 알아도 무방하다면서 메서드의 인자를 이용해 의존성을 해결할 수도 있다.

유연한 설계

의존성은 객체들의 협력을 가능하게 만드는 매개체라는 관점에서는 바람직한 것이다. 단, 과하면 문제가 된다. 문제는 의존성의 존재가 아니라 의존성의 정도다.
ex) Movie가 협력하고 싶은 대상이 반드시 구현체의 인스턴스일 필요는 없다.
바람직한 의존성은 재사용성과 관련이 있다. 컨텍스트에 독립적인 의존성은 바람직한 의존성이고 특정한 컨텍스트에 강하게 결합된 의존성은 바람직하지 않은 의존성이다.
의존성의 정도를 나타내는 것을 결합도라고 한다.

지식이 결합을 낳는다

ex) 그저 할인 요금을 계산한다는 사실만 알고 있을 뿐이다. 의존하는 경우 알아야 하는 지식의 양이 적기 때문에 결합도가 느슨해진다.

추상화에 의존하라

  • 구체 클래스 의존성
  • 추상 클래스 의존성
  • 인터페이스 의존성
인터페이스에 의존하면 상속 계층을 모르더라도 협력이 가능해진다. 의존하는 대상이 더 추상적일수록 결합도는 더 낮아진다.

명시적인 의존성

생성자의 인자로 선언하는 방법은 Movie가 DiscountPolicy 에 의존한다는 사실을 Movie의 퍼블릭 인터페이스에 드러내는 것이다. 이를 명시적인 의존성이라 한다.
내부에서 직접 인스턴스를 생성할 경우 숨겨진 의존성이라고 한다. 의존성은 명시적으로 표현돼야 한다.

new 는 해롭다.

  • 구체 클래스를 직접 명시하므로 결합도가 높아진다.
  • 구체 클래스뿐만 아니라 어떤 인자를 이용해 클래스의 생성자를 호출해야 하는지도 알아야 한다.
  • 즉, 지식의 양이 늘어나기 때문에 결합도가 높아진다.
결합도가 높으면 변경에 의해 영향을 받기 쉬워진다.
해결 방법은 인스턴스를 생성하는 로직과 사용하는 로직을 분리하는 것. 생성의 책임은 클라이언트가, 사용의 책임은 서비스로직이..
  1. 사용과 생성의 책임을 분리하고
  1. 의존성을 생성자에게 명시적으로 드러내고
  1. 구체 클래스가 아닌 추상 클래스에 의존하게 하라.

가끔은 생성해도 무방하다.

주로 협력하는 기본 객체를 설정하고 싶다면.

표준 클래스에 대한 의존은 해롭지 않다.

ArrayList 의 코드가 수정될 확률은 0에 가깝기에.. List<Integer> list = new ArrayList<>(); 처럼 사용하라.
따라서 의존성에 의한 영향이 적은 경우에도 추상화에 의존하고 의존성을 명시적으로 드러내라.

컨텍스트 확장하기

예외 케이스가 추가될 때마다 기존의 협력 방식을 따라 새롭게 추가하라. 결합도를 낮춤으로써 얻게 되는 컨텍스트의 확장이라는 개념이 유연하고 재사용 가능한 설계를 만드는 핵심

조합 가능한 행동

어떤 객체와 협력하느냐에 따라 객체의 행동이 달라지는 것은 유연하고 재사용 가능한 설계가 가진 특징이다. 유연하고 재사용 가능한 설계는 객체가 무엇(what)을 하는지를 표현하는 클래스들로 구성된다. 의존성을 관리하는 것이 중요한 핵심이다.