2021 11 04
2021-11-04¶
우아한객체지향 특강¶
- 참고: https://www.youtube.com/watch?v=dJ5C4qRqAgA
- Dependency - 변경에 의해 변경의 영향을 받을 수 있는 것 - B가 변경될 때 A도 변경될 수 있다는 것!
- 클래스 의존성의 종류
- Association (연관관계)
- 영속적인 탐색구조를 가져야할 때
- 영속적인 연관관계
- Dependency (의존관계) - 일시적으로 해당 객체가 필요할 때 - 일시적인 연관관계
- Inheritance (상속관계)
- Realization (실체화관계)
- 패키지에 포함된 클래스 사이의 의존성 - 클래스 사이에서 의존성이 있다면, 패키지 사이에 의존성 있다고 보면 됨
- 양방향 의존성을 피할 것!
- A가 바뀔때 B가 바뀌고, B가 바뀔때 A가 바뀐다?
- 이건 원래 같은 클래스여야했던 것을 둘로 찢어논 수준이야
- 가급적이면 의존성을 "단방향"으로 구성하세요
- 또한 의존성의 방향을 다중성이 적은 방향을 선택하도록 하세요
- 비추! XXX
- 추천! OOO ```java class A { } class B { private A a; } ```- 의존성이 필요없다면 뺴세요! - 패키지 사이의 의존성 사이클을 제거할 것 - 정리! 1. 양방향을 피해라! 2. 다중성이 적은 방향을 택해라! 3. 불필요한 의존관계 제거해라! 4. 패키지 사이의 의존성 제거해라!
- 개선할 설계 포인트 - 내 설계가 어떤지 알고 싶다면, 종이와 펜을 잡고 직접 참조 관계를 그려볼 것 - 객체 참조를 쓴다면... 이는 "결합도 상승"으로 이어짐 - 패키지 의존성간에 사이클이 발생할 수 있음 - 패키지끼리 의존성이 있으면 나쁜거야??? - 성능 문제가 발생함. 다음과 같은 사안들을 고민해야함 - 어디까지 조회해야하지? - 수정시 도메인 규칙을 적용할 경계는 어디이지? - 트랜잭션의 경계를 어디까지로 잡아야하지? - 트랜잭션 경합으로 인한 성능저하 발생 - ex. 의존관계가 있는 Delivery -> Order -> Shop 생각해보면 셋의 생성/수정/삭제 사이클이 다 달라 - Delivery: 배달 시작/중간/완료의 사이클 - Order: 사용자의 주문 담기/변경/완료의 사이클 - Shop: 가게의 오픈/휴식/닫음의 사이클
- 객체 참조에 대해 다시 생각해보자 - 객체 참조의 문제점: Everything is Connected - 해결책 - Repository를 통한 탐색 (약한 결합도) - 인스턴스 변수로 Entity를 박아두는게 아니라, 필요한 id를 박아두기 - 어떤 객체를 묶고, 어떤 객체를 분리해야지? - 정해진 Rule은 없지만... - 함께 생성/삭제되는 객체 - 도메인 제약사항 공유하는 객체 - 가능하면 분리하도록 하자! - 얘가 바뀔때 얘는 꼭 바뀔필요까진 없겠구나? <= 객체 참조 절단의 대상 - 객체를 묶을때 Transaction의 단위로 묶자 - 동일 Transaction: 동일 패키지, 객체 참조 - 다른 Transaction: Id만 가지고 있자
- 인스턴스 변수를 객체에서 Id로 가지게 되면 컴파일 에러는??? - 필요한 Validation 로직 모으기 - Validator 빈을 만들고 로직을 다 때려넣자 - 때로는 절차지향이 객체지향보다 좋을 수 있다!
- 순차적으로 실행되어야 하는 도메인 로직! - 찢어놨지만, A가 바뀌면 그에따라 B가 바뀌어햐 해요! 1. 절차지향 로직 도입 - 위의 Validation과 동일 2. Domain Event Publishing - Event 발급하여 어플리케이션 컨텍스트의 도움을 받자!
- [정리] 패키지 의존성을 제거하는 3가지 방법 1. 중간 객체 만들기 2. 의존성을 interface/abstract_class로 역전시키기 3. 새로운 패키지로 추가 - 도메인 단위 모듈 = 시스템 분리의 기반!