1 minute read

의존성

의존성이란 변경에 의해 영향을 받을 수 있는 가능성이다.

설계를 간단하게 표현하면 코드를 어떻게 배치시킬 것인지 결정하는 것 즉, 어떤 패키지에 어떤 코드를 넣고 어떤 클래스에 어떤 코드를 넣는지이다. 설계를 할 때 초점을 맞춰야할 것은 변경이다. 같이 변경되는 코드는 같이 넣어야되고 같이 변경하지 않는 것은 따로 넣어야 한다.

image

위 클래스 다이어그램에서 A가 B를 의존한다고 하고 B가 변경될 때 A도 함께 변경될 가능성이 있다.

의존성에는 2가지 종류가 있다.

  • 클래스 사이의 의존
  • 패키지 사이의 의존


클래스 의존성 종류

  • 연관관계
class A {
  private B b;
}
  • 의존관계
class A {
  B method (B b);
}
  • 상속 관계
class A extends B {
}
  • 실체화 관계
class A implements B {
}


패키지 의존성

image

패키지 A가 패키지 B를 의존한다는 것은 패키지 B에 있는 클래스가 변화하면 패키지 A에 있는 클래스 변경이 일어날 수 있다는 것이다.


좋은 의존성을 설계하는 방법

  • 양방향 의존성을 피한다. (최대한 단방향으로)

  • 다중성이 적은 방향을 선택한다. (컬렉션보다는 단일 객체)
  • 의존성이 필요없다면 제거한다.
  • 패키지 사이의 의존성 사이클을 제거한다.
  • 패키지 사이에도 양방향 의존성을 제거한다.

image

패키지 한개가 변경되면 3개 모두 변경될 수 있는 것으로 패키지 3개가 1개인 경우나 틀림없다.

설계의 가장 중요한 부분은 어떻게 변화가 전파되는가다.


객체 간의 협력

객체간에 메시지를 주고받으면서 협력하면서 관계가 생기는데 관계는 방향성이 필요하다. (관계의 방향 = 협력의 방향 = 의존성의 방향)

또한 관계의 종류를 결정해야 한다.

  • 연관 관계 (탐색 가능성) - 영구적인 탐색 구조로 객체에서 어떤 객체를 빈번하게 필요하거나 함께 변형되는 경우에 설정하기 좋다.
  • 의존 관계 - 협력을 위해 일시적으로 필요한 의존성 (파라미터, 리턴타입, 지역 변수)


설계 개선하기

설계를 진화 시키기 위한 출발점으로는 코드 작성 후 의존성 관점에서 설계를 검토하자

결합도가 높은 직접 참조에서 간접 참조로

객체에서 다른 객체들을 무조건 객체 참조(연관관계 설정)를 하면 결합도가 상승하게 된다. 또한 성능문제도 발생할 수 있다. 수정시 도메인 규칙을 함께 적용할 경계(트랜잭션 경계)를 설정하는 것이 모호하다. 많은 테이블을 하나의 단위로 잠금을 설정하게 되면 프로그램에 지연이 많이 될 것이다. 예를 들어 가게, 주문, 배달 엔티티가 있는데 주문이 될 때마다 이 3개의 엔티티를 하나의 단위로 설정하게 되면 트랜잭션의 범위가 너무 커진다. 이런 경우에 객체 참조가 꼭 필요한지 생각해보면 좋다.

변경의 빈도가 다르다면 객체 직접 참조가 아닌 간접 참조를 하여 결합도 수준을 내리면 좋다. 객체를 참조하는 것이 아닌 id를 필드로 가지고 있게 하여 repository를 통해 탐색하게 하자. id로 연관관계를 끊고 그 단위로 트랜잭션을 관리하자.

어떤 객체를 묶고 어떤 객체를 분리할 것인가

  • 함께 생성되고 함께 삭제되는 객체를 함께 묶자
  • 도메인 제약사항을 공유하는 객체를 함께 묶자
  • 가능하면 분리하자

Categories:

Updated: