2021-06-25-TIL
의존성의 관리
설계란 무엇인가? 코드를 어떻게 배치할 것인가에 대한 의사결정. 어떤 패키지에 어떤 프로젝트에 코드를 넣을 것인가에 대한 고민들. 핵심은 ‘변경’ 같이 변경되는 것들끼리 묶는 것이 바람직하다. 변경은 곧 의존성이다.
의존성
B가 변경될 때 A도 변경될 수 있다. 그 가능성을 의존성이라고 한다. 의존성이 있다고 해서 반드시 바뀌는 것은 아니다. 설계를 잘 하면 변경에 대하여 무조건 바뀌지는 않는다. (설계를 잘하면)
UML의 정의도 같다. 한 요소의 정의가 바뀔 때 다른 요소가 바뀔 수 있으면 두 요소 사이에 의존이 있다고 보고, 이 관계는 한 방향이다.
클래스 의존성
- 연관관계
- A -> B로 영구적으로 갈 수 있는 관계
- 의존관계
- A -> B로 갈 수도 있는 관계
- 상속관계
- 구현이 바뀌더라도 영향을 받음
- 실체화 관계
- 시그니처가 바뀌면 영향을 받음
패키지 의존성
- 양방향
1
2
3
4
5
6
7
8
class A {
private B b;
public void setA(B b) {
}
}
- 단방향
JPA를 사용하면 성능 이슈가 많이 발생하게 되는데, 다중성이 적은 의존성의 방향을 선택하는 것이 유리하다. 예를 들어, A가 B의 리스트를 가지는 것보다는 B가 A의 참조를 하나 가지는 것이 낫다는 것이다. 가장 좋은 것은 불필요한 의존성을 빼버리는 것이다.
패키지 3개가 a->b->c->a라면 결국 하나의 패키지라는 것이다. 이것이 가장 기본적인 의존성 관리의 법칙이다. 의존성의 사이클이 생기지 않도록 해야 한다.
이 규칙은 Robert C. Martin이 정리한 비순환 의존성 원칙(Acyclic Dependencies Principle)이다. 패키지나 컴포넌트의 의존성 그래프에 사이클이 없어야 하고, 따라서 의존성은 방향 비순환 그래프(DAG)를 이뤄야 한다. 위키백과의 예시처럼 B -> D -> C -> B 같은 사이클은 끊어야 원칙을 지킬 수 있다.
가게와 메뉴: 장바구니 주문 검증
장바구니 데이터는 보통 로컬에 저장을 한다. 서버에 저장을 하지는 않는다. 여기서 발생할 수 있는 문제가 있다. 예를 들어, 사장님이 판매하고자 하는 데이터를 삭제하게 되면 장바구니의 데이터와 판매 상품의 불일치가 발생하게 된다. 따라서 주문 데이터와 실제로 있는 데이터와의 일치 여부를 검증하는 것이 필요하다.
처음엔 메뉴-주문항목, 옵션그룹-주문옵션그룹, 옵션-주문옵션을 모두 비교해야 한다. 즉, 바뀔 수 있는 값에 대해 상호검증이 모두 들어가야 한다. 추가적으로 가게가 영업 중인지, 최소주문금액을 충족하는지를 한 번 더 검증을 해야 한다.
검증 로직을 하나하나 태워야 한다. 첫 번째로 주문금액이 최소주문금액 이상인지 확인 -> 가게가 영업 중인지 확인 -> 옵션의 가격과 주문옵션의 가격이 같은지 비교 -> 옵션의 이름과 주문옵션의 이름 비교 -> 옵션그룹의 이름과 주문옵션그룹의 이름 비교 -> 메뉴의 이름과 주문항목 이름 비교
관계의 방향 = 협력의 방향 = 의존성의 방향
연관관계 -> 협력을 위해 필요한 영구적인 탐색 구조
Order가 Shop으로 가는 경우가 간혹 한 번 있다면 이것을 연관관계가 있다고 보기 어렵다. 그런데 이것이 아주 빈번하다면 연관관계라고 볼 수 있다.
핵심은 연관관계로 갈 것인지, 의존관계로 갈 것인지가 아니라 방향성이다.
- 연관관계 = 탐색가능성(navigability) 어떤 객체가 있는데, 이 객체를 알면 다른 객체를 찾아갈 수 있음을 뜻한다.
- 연관관계와 협력 어떤 객체를 참조하려면 어떤 객체가 있어야 해 라는 타당성이 있어야 한다.
UML 클래스 다이어그램에서도 연관은 한 방향 또는 양방향으로 탐색 가능할 수 있고, 열린 화살표는 반대편에서 그 클래스로 실행 시점에 효율적으로 도달할 수 있다는 뜻이다. 즉 화살표 방향이 곧 누가 누구를 아는지, 누가 누구에게 의존하는지를 나타낸다.
참고한 자료외부 출처 2
외부 출처
- Acyclic dependencies principle
- Class diagram의존, 연관, 탐색 가능성
댓글
아직 댓글이 없습니다