본문 바로가기
OOP/<오브젝트>, 조영호

9장 의존성 관련 조언

by 민휘 2024. 1. 25.

유연한 설계는 유연성이 필요할 때만 옳다

  • 설계의 미덕은 단순함과 명확함이다. 변경에 대한 막연한 불안감은 불필요하게 복잡한 설계를 유발한다.
  • 유연함은 단순함과 명확함의 희생 위에서 자란다. 단순함과 명확함을 만드는 방법은 사람들 간의 커뮤니케이션 뿐이다. 복잡성이 필요한 이유와 합리적 근거 없이는 누구도 복잡한 설계를 만족스러운 해법으로 여기지 않을 것이다.
  • 단순하고 명확한 해법이 그런대로 만족스럽다면 유연성은 제거하라. 유연성은 코드를 읽는 사람들의 복잡함을 수용할 수 있을 때만 가치가 있다. 하지만 복잡성에 대한 걱정보다 유연하고 재사용 가능한 설계의 필요성이 더 크다면 코드의 구조와 실행 구조를 다르게 만들어라.
  • 의존성을 관리하는 것보다 더 중요한 것은 협력에 참여하는 객체가 다른 객체에게 어떤 메시지를 보내는지가 더 중요하다.
  • 객체의 생성 책임은 마지막에 결정한다. 더 중요한 것은 마치 객체가 이미 존재하는 것처럼 이들 간의 관계를 신경 쓰는 일이다.

 

OCP

  • 컴파일 타임 의존성은 유지하면서 런타임 의존성의 가능성을 확장하고 수정하는 구조
  • 핵심은 추상화. 변하는 것과 변하지 않는 것을 구분해야 한다.
  • 생략되지 않고 남아있는 부분은 컴파일 타임에 의존성이 변하지 않고, 변하는 부분은 런타임에 의존성이 주입된다.

 

생성 사용 분리

  • 의존하는 필드의 생성 책임을 클라이언트로 옮기면, 원래 클래스는 특정한 구현체에 독립적이다.
  • 구현체 선택으로 인해 클라이언트가 특정 맥락에 묶이는 걸 원하지 않는다면, 생성 책임만을 가진 별도의 클래스를 둘 수 있다.
  • 객체 지향 설계에서는 도메인에 책임을 할당하는 것만으로는 품질을 달성하지 못한다. 품질 균형에 필요한 인공적인 객체를 추가해야 한다.

 

의존성 주입

  • 의존성을 숨기는 방법은 나쁘다. 의존성 설정 시점과 의존성이 해결되는 시점이 멀어서, 의존성 문제가 있을 때 런타임에 발견된다. 전역객체를 사용하게 되므로 테스트에서 의존성을 의도적으로 끊어야 한다. 결정적으로 내부를 노출하므로 캡슐화 위반이다.
  • 의존성 주입 : 의존성을 퍼블릭 인터페이스에 드러내 외부에서 런타임 의존성을 명시적으로 전달하는 방식
  • 생성자 주입 > 세터 주입 : 세터 주입은 누락할 경우 불완전 상태의 객체가 나온다. 생성자로 완전한 상태의 객체를 초기화하는 것이 좋다.
  • 메소드 주입 : 특정 메소드가 의존성을 필요로 하는 유일한 경우라면 사용한다.

 

의존성 역전

  • 하위 수준의 클래스 변경이 상위 클래스에 영향을 미치면 안된다. 상위 클래스의 변경은 하위 클래스에 영향을 미칠 수 있다.
  • 상위, 하위 클래스 둘다 추상화에 의존해야 한다.
  • 패키지에 의존성 역전을 적용할 수 있다. 인터페이스 소유권을 역전시킨다. 패키지를 컴파일할 때 구체적인 클래스에 의존하게 되면 연관된 패키지를 모두 다시 컴파일한다. 불필요한 빌드를 줄이기 위해 인터페이스를 상위 수준의 패키지로 이동시킨다.
  • 상위 수준의 협력을 재사용하기 위함이다.

'OOP > <오브젝트>, 조영호' 카테고리의 다른 글

11장 합성과 유연한 설계  (1) 2024.01.30
10장 상속과 코드 재사용  (0) 2024.01.29
8장 의존성 관리하기  (0) 2024.01.25
7장 패러다임 역사  (0) 2024.01.19
6장 퍼블릭 인터페이스 설계  (0) 2024.01.18