Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Archives
Today
Total
관리 메뉴

csct3434

[만들면서 배우는 클린 아키텍처] 02. 의존성 역전하기 본문

개발 서적/만들면서 배우는 클린 아키텍처

[만들면서 배우는 클린 아키텍처] 02. 의존성 역전하기

csct3434 2024. 3. 3. 20:57

단일 책임 원칙

  • 일반적인 해석 (오해) : ‘하나의 컴포넌트는 오로지 한 가지 일만 해야 하고, 그것을 올바르게 수행해야 한다’
  • 실제 정의 : ‘컴포넌트를 변경하는 이유는 오직 하나뿐이어야 한다’
  • 아키텍처에서 단일 책임 원칙의 의미
    • 컴포넌트를 변경할 이유가 한 가지라면, 어떤 다른 이유로 소프트웨어를 변경하더라도 해당 컴포넌트에 대해서는 신경쓸 필요가 없다는 것
    • 컴포넌트의 의존성 각각은 이 컴포넌트를 변경하는 이유 하나씩에 해당
      • 컴포넌트 A : 모든 컴포넌트에 의존하고 있기 때문에 다른 어떤 컴포넌트가 바뀌든지 같이 변경해야 함
      • 컴포넌트 E : 의존하는 컴포넌트가 없기 때문에 E를 변경할 이유는 새로운 요구사항에 의해 E의 기능을 바꿔야 할 때 뿐

의존성 역전 원칙

  • 의존성 역전 원칙의 정의 : '코드상의 어떤 의존성이든 그 방향을 바꿀 수 있다'
    • 의존성의 양쪽 코드를 모두 제어할 수 있을 때만 역전 가능, 예로 서드파티 라이브러리에대한 의존성은 역전 불가능
  • 의존성 역전 원칙의 필요성
    • 계층형 아키텍처에서 도메인 계층은 영속성 계층에 대한 의존성 때문에 영속성 계층을 변경할 때마다 잠재적으로 도메인 계층을 변경해야 함
    • 도메인 코드는 애플리케이션에서 가장 중요한 코드이기에, 영속성 코드가 바뀐다고 해서 도메인 코드를 바꾸는 것은 적절하지 않음
    • 이러한 의존성을 제거할 수 있는 방법이 바로 의존성 역전
  • 적용 예시

변경 전

  • 도메인 계층의 서비스가 영속성 계층의 엔티티와 레포지토리에 의존하는 상태
  • 엔티티는 도메인 객체를 표현하고, 도메인 코드는 엔티티의 상태를 변경

변경 후

  • 엔티티를 도메인 계층으로 올리면 순환 의존성이 발생함
    • 영속성 계층(리포지토리) → 도메인 계층(엔티티)
    • 도메인 계층(서비스) → 영속성 계층(레포지토리)
  • 이러한 순환 의존성에 DIP를 적용한다
    • 도메인 계층에 레포지토리에 대한 인터페이스를 만들고, 실제 레포지토리는 영속성 계층에서 구현
    • 도메인 계층에 인터페이스를 도입함으로써 의존성을 역전시킬 수 있고, 그 덕분에 영속성 계층이 도메인 계층에 의존하게 된다

클린 아키텍처

 

  • 비즈니스 규칙은 프레임워크, 데이터베이스, UI 기술, 그 밖의 외부 애플리케이션이나 인터페이스로부터 독립적임 → 도메인 코드가 바깥으로 향하는 어떤 의존성도 존재하지 않음
  • 의존성 역전 원칙의 도움으로 모든 의존성이 도메인 코드(안쪽)를 향함
  • 유스케이스 : 앞서 서비스라고 불렀던 것들, 단일 책임을 갖기 위해 조금 더 세분화 되어 있음 → 이를 통해 넓은 서비스 문제를 방지
  • 도메인 코드에서는 영속성 프레임워크와 UI 프레임워크에 대한 정보가 없기 때문에, 특정 프레임워크에 특화된 코드를 가질 수 없음 → 비즈니스 규칙에 집중하며 도메인 코드를 자유롭게 모델링 가능
  • 도메인 계층이 외부 계층과 철저하게 분리돼야 하므로 애플리케이션의 엔티티에 대한 모델을 각 계층에서 유지보수 함
    • ex) 영속성 계층에서 ORM 프레임워크를 사용하는 경우
      • 도메인 계층과 영속성 계층에서 각각 엔티티를 만들어야 함
      • 도메인 계층과 영속성 계층이 데이터를 주고받을 때, 두 엔티티를 서로 변환해야 함
    • 도메인 코드를 프레임워크에 특화된 문제로부터 해방시켜 결합을 제거하기 때문에 이는 바람직함

육각형 아키텍처 (헥사고날 아키텍처, 포트 & 어댑터 아키텍처)

  • 클린 아키텍처의 추상적인 원칙들을 조금 더 구체적으로 적용한 아키텍처
  • 어댑터
    • 좌측 : Driving Adapter, 애플리케이션을 주도하는(코어를 호출하는) 어댑터
    • 우측 : Driven Adapter, 애플리케이션이 주도하는(코어가 호출하는) 어댑터
  • 포트
    • 애플리케이션이 어댑터들과 통신하려면, 코어가 각각의 포트를 제공해야 함
    • Driving Adapter에서 포트는 어댑터에 의해 호출되는 인터페이스이고, 코어의 유스케이스 클래스가 이를 구현함
    • Driven Adapter에서 포트는 코어에 의해 호출되는 인터페이스이고, 어댑터가 이를 구현함

정리

  • 클린 아키텍처와 육각형 아키텍처는 (DIP) 의존성을 역전시켜 (SRP) 도메인 코드가 다른 외부 코드에 의존하지 않도록 한다
  • 이를 통해, 도메인 로직을 영속성과 UI에 특화된 모든 문제로부터 분리하여 도메인 코드를 변경할 이유를 줄일 수 있다
  • 또한 도메인 코드는 비즈니스 문제에 딱 맞도록 자유롭게 모델링될 수 있고, 영속성 코드와 UI 코드도 각각의 문제에 맞게 자유롭게 모델링될 수 있다