콘텐츠로 이동

2021 11 04

2021-11-04

우아한객체지향 특강

  • 클래스 의존성의 종류 - Association (연관관계) - 영속적인 탐색구조를 가져야할 때 - 영속적인 연관관계
    class A {
        private B b;
    }
    

    - Dependency (의존관계) - 일시적으로 해당 객체가 필요할 때 - 일시적인 연관관계

    class A {
        private B method(B b) {
          return new B();
        }
    }
    

    - Inheritance (상속관계)

    class A extends B {
    }
    

    - Realization (실체화관계)

    class A implements B {
    }
    

  • 패키지에 포함된 클래스 사이의 의존성 - 클래스 사이에서 의존성이 있다면, 패키지 사이에 의존성 있다고 보면 됨
  • 양방향 의존성을 피할 것! - A가 바뀔때 B가 바뀌고, B가 바뀔때 A가 바뀐다? - 이건 원래 같은 클래스여야했던 것을 둘로 찢어논 수준이야 - 가급적이면 의존성을 "단방향"으로 구성하세요 - 또한 의존성의 방향을 다중성이 적은 방향을 선택하도록 하세요 - 비추! XXX
    class A {
        private Collection<B> bs;
    }
    class B {
    }
    
      - 추천! 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. 새로운 패키지로 추가 - 도메인 단위 모듈 = 시스템 분리의 기반!