[영상후기] [10분 테코톡] 누누, 다즐의 클린 아키텍처

박철현·2025년 6월 6일

영상후기

목록 보기
160/161

movie

목차

  • 소프트웨어 아키텍처란?
  • 레이어드 아키텍처
  • 클린 아키텍처
  • 헥사고날 아키텍처
  • 마치며

소프트웨어 아키텍처

아키텍처

  • 어떤 대상의 구성과 동작원리, 구성 요소간의 관계 및 시스템 외부환경과의 관계를 설명하는 하나의 설명서
    • 간단히 시스템의 설계 및 동작하는 방식

소프트웨어 아키텍처

  • 소프트웨어 구성요소들 사이 관계를 표현하는 설명서

소프트웨어가 제공하는 가치

  • 기능

    • 작성한 코드가 기능이기 때문에 기능의 가치
  • 구조

  • 보통 기능 > 구조 라 생각

    • 애플리케이션 기능이 동작해야 가치 존재

구조가 더 중요하다

  • 클린 아키텍처의 저자인 로버트 마틴은 구조가 더 중요하다고 설명

  • 방(구조)에 물건(기능) 배치하는 상황

    • 물건을 막무개내로 넣을 시 물건을 추가로 넣을 수 없음
      • 기능은 많지만 너무 복잡한 구조
    • 물건 배치를 순차대로 넣을 시
      • 새로운 물건을 추가 시 구조가 잘 잡혀 있으니 어디 위치할지 파악 및 배치하기도 쉬움
  • 좋은 구조를 가지도록 코드 설계해야 한다.

왜 구조가 중요할까?

  • 소프트웨어 비용과 관련됨
    • 개발 초기 단계 : 개발 비용이 더 높음
    • 개발 완료 단계 : 변화하는 소프트웨어 유지보수
  • 장기적으로 봤을 때 기능 개발 비용 > 유지 보수 비용

기능 좋음 + 구조 부족 vs 기능 부족 + 구조 좋음

비교특징
기능 좋음 + 구조 부족당장은 좋지만 수정 비용이 너무 크다. 언제 버려질 지 모른다.
기능 부족 + 구조 좋음당장은 부족하지만 수정하는데 비용이 적다. 개선, 확장에 유연하다.

좋은 구조를 만드는 방법

  • 패러다임, 설계 원칙(SOLID), 응딥 원칙, 결합 원칙(응집도 높이고 결합도 낮추며 개발)

  • 모든 것을 지키면서 개발하기 어려움

아키텍처 패턴

  • 계층형 아키텍처 / 클린 아키텍처 / 헥사고날 아키텍처
    • 원칙을 지킬 수 있도록 도와준다!
  • 아키텍처 적용함으로써 소프트웨어를 통해 이루고자 하는 핵심 목표인 도메인을 지킬 수 있음
  • 외부 요소인 UI, DB, API 같은 것에 도메인이 의존하지 않도록 도메인 보호

레이어드 아키텍처

  • 관심사가 같은 코드들을 계층으로 그룹화
  • Presentation, Application, Persistence 계층으로 나눠 사용하고 필요에 따라 계층을 추가해서 사용할 수 있음

특징

  • 계층화로 인한 분리된 책임
  • 편의에 따라 여러 계층 추가 가능
  • 구조가 쉽고 단순하고 익숙
  • 데이터베이스 주도 설계가 될 수 있음

문제점

  • Presentation, Application, Persist 순 의존성 발생
    • 상위 레이어(Presentation Layer)가 하위 레이어(Persistence Layer)를 알 수 있는 상황을 만들게 됨
    • 하위 레이어 변경이 상위 레이어 변경을 영향을 주게 됨
      • Persistence Layer의 변화가 Application Layer의 변화를 유발하고 프레젠테이션 계층까지 수정이 필요해짐 (의존성을 가짐)
    • 한 계층의 변화가 다른 계층까지 영향을 주기 때문에 코드 변경이 어려워짐

클린 아키텍처

  • 의존성 역전을 통해 도메인이 중심
    • 프로젝트 전체가 DB가 아닌 도메인에 의존하게 하는 방법으로 문제 해결

특징

  • 핵심 규칙을 담고 있는 도메인이 중심
  • 도메인이 세부 사항에 의존하지 않는다.
    • 세부사항 : 입출력 장치, 디비, 웹시스템, 서버, 프레임워크, 통신 프로토콜 등
  • 익숙하지 않을 수 있고 레퍼런스가 적다.

구분

Entity와 Use Cases가 있는 계층 (안쪽)

  • 비즈니스 로직을 캡처한 계층
  • 외부 요소에 대해 절대로 알면 안됨

외부요소가 존재하는 계층 (밖)

  • 어떤 DB, 프레임워크를 사용하는지

구성

  • 클린 아키텍처는 총 4개의 레이어로 구성

Entity 레이어

  • 가장 핵심적인 비즈니스 로직이나 규칙을 담고있는 레이어
    • 엔터프라이즈 비즈니스 규칙(Entities)
    • 애플리케이션의 핵심적인 엔티티나 도메인 객체
    • 비즈니스 로직이나 규칙을 나타내며 외부 요소에 대한 어떠한 의존성도 없다.
  • 대부분 프로젝트에서 도메인 패키지에 들어있는 것들

Use Case 레이어

  • 애플리케이션 비즈니스 규칙 (Use Cases)
    • 특정 비즈니스 로직을 포함하며 데이터 저장, UI 등은 관심 없다.
  • 보통 Repository에서 객체를 받아와서 특정 행위를 하고 업데이트 하는 부분 처리

Adapter 레이어

  • 인터페이스 어댑터(Interface Adapters)
    • 데이터를 애플리케이션(Use Case)에서 사용하는 형태로 변환하거나 내부에서 사용하는 데이터를 외부에 적합한 형태로 변환

Infrastructure 레이어

  • DB와 프레임워크 같은 외부와 통신 작업을 해주는 것들

  • 외부 요소 (Frameworks & Drivers)

    • 특정 프레임워크나 기술에 의존하는 부분

클린 아키텍처는 추상적이다.

  • 어디서부터 어디까지를 Entity에 넣어야 하는지, 어디까지를 Use Cases에 넣어야 할지 등 세부 사항 알기 쉽지 않음

  • 정확히 어떻게 하라는 지침 존재하지 않음

헥사고날 아키텍처

  • 클린 아키텍처와는 약간 다르겠지만 클린 아키텍처를 적용하기에 아주 좋은 레퍼런스가 될 수 있는 아키텍처로 헥사고날 아키텍처가 있음

  • 가장 중요한점은 외부 요소와 핵심 비즈니스 로직이 소통할 때 포트를 통해 간접적으로 통신해야 함

특징

  • 큰 비즈니스 가치를 가지고 있는 도메인 모델에 큰 관심
  • 레퍼런스가 클린 아키텍처에 비해 많다.
  • 포트와 어댑터를 구성하고 관리하는데 복잡성이 따른다.
  • 도메인에 라이브러리를 직접 활용하기 어렵다.

구성

도메인 모델 (Domain Model)

  • POJO로 이루어진 Entity와 Use Case는 클린 아키텍처의 Entity와 Use Case와 유사
    • POJO : Plain Old Java Object의 약자로 순수한 오래된 자바 객체
      • 즉 Java로 생성하는 순수한 객체
      • Java나 Java 스펙에 정의된 것 이외에 다른 기술이나 규약에 얽메이지 않아야 함
      • 특정 환경에 종속적이지 않아야 함(특정 프레임워크나 웹 기술 담고있는 클래스 또는 인터페이스 사용X)
      • 출처 : [Spring] POJO란 무엇인가?
  • 어플리케이션의 핵심 기능, 비즈니스 로직이나 규칙을 캡슐화

포트 (Port)

  • 애플리케이션의 도메인 모델과 외부의 통신 인터페이스 정의

  • 도메인 모델과 외부 통신 인터페이스 정의

  • Use case에서 포트를 구현하거나 Use Case에서 포트를 호출해 외부 요소와 통신할 수 있습니다.

어댑터 (Adapter)

  • 특정 포트에 연결되어 외부와 도메인간 통신을 가능하게 한다.
    • 외부 요소(웹 요청, 데이터베이스 등) 실제 통신 발생
  • 포트를 구현하기도 하며 포트를 통해 Use case를 직접 호출하기도 합니다.

다른 방식으로 보는 방법

입력포트 & 어댑터

  • 입력포트는 동작을 유발하는 외부 요청 처리
  • Use case를 호출하는 입력 포트 입력 어댑터

출력포트 & 어댑터

  • Use case로부터 호출되어 외부에 결과를 전달하는 것들을 출력 포트, 출력 어뎁터라 볼 수 있음

좀 더 직관적 그림

  • 동그라미 친 부분은 외부 라이브러리와 프레임워크를 연결하는 부분 담당하는 어댑터

    • Controller에서는 Port에만 접근할 수 있고 이를 통해 Use Case를 호출
    • Use Case에서는 도메인 쪽에 구현되어 있는 Repository 포트를 통해서 결과를 보장합니다.
  • 이 과정으로 도메인을 POJO로 유지할 수 있고 외부 라이브러리나 프레임워크의 변화로부터 도메인을 보호할 수 있습니다.

헥사고날 아키텍처 어떻게 적용할까?

  • 서비스와 레포지토리 메서드를 인터페이스로 추출하는 것

    • service의 public 메서드 추출해서 MemberUseCase 생성
    • MemberJpaRepository 메서드 추출해서 emberRepository인터페이스를 만듭니다.
  • 도메인 분리

    • Jpa Member를 Service에서 직접 사용하지 않고 도메인의 Member를 따로 구현하여 서비스에서 이를 의존하도록 바꿔 패키지간 양방향 의존성 끊을 수 있음
  • 패키지 네이밍 변경으로 작업은 끝남

  • 변경 전 Layered Architecture

  • 변경 후 헥사고날 아키텍처의 패키지

    • in/out 등 포트 구체화

이 부분은 다른 실제 코드 예시 기반 새 포스팅으로 작성하겠습니다.

마치며

큰 프로젝트 사례 - 헥사고날 아키텍처 적용 타 유튜브 영상

  • 라인 : 1.15배 / 파일 수 : 1.5배 / 패키지 수 4.28배 증가
  • 레이어드 아키텍처와 비교해서 코드 양과 복잡도 증가

클린 아키텍처를 적용하면 항상 좋은가?

  • 의존 관계가 복잡하지 않다면 레이어드 아키텍처가 좋은 방안일수도 있음

이럴 때 고려해보세요.

  1. 대규모 프로젝트 진행할 때
  2. 프로젝트 일원 모두 클린 아키텍처를 이해할 때
  3. 외부 요소가 변화가 잦을때
profile
비슷한 어려움을 겪는 누군가에게 도움이 되길

0개의 댓글