[항해 플러스 5기 백엔드 2주차] 클린 아키텍처

다양한 아키텍처를 알아야 할까?

모두 적용하는 건 아니지만 학습은 해야 한다

아키텍처는 준수해야 하는 제약을 넣는 것이라 볼 수 있다.

단순히 요구사항을 만족하는 기능을 개발하고 끝나는게 아니라, 앞으로 유지보수 가능하고 지속적으로 성장 가능한 구조를 고민해야 한다. 이를 위해선 규칙이 필요하여 이러한 규칙은 아키텍처를 학습하고 적용하여 지킬 수 있다.

좋은 아키 텍처 패턴은

  • 지속적으로 성장 가능한 안정적인 소프트웨어를 잡기 위한 가이드 라인
  • 지켜야 할 기본적인 개발 가이드 라인을 잡아주는 틀

클린 코드의 중요성

비즈니스 로직의 복잡할 수록 코드도 복잡해 진다. 구현에만 초점을 맞춘다면 하나의 클래스에 10,000줄이 넘는 코드가 작성될 수도 있고 하나의 메서드에서 코드의 depth가 10 depth가 넘어갈 수도 있다.

(설마 하겠지만 레거시 코드 중에 진짜 10 depth가 넘는 코드를 본 적이 있다..)

대부분은 자기가 작성한 코드도 몇주 혹은 몇개월이 지난뒤 다시 보았을 때 이해하기 힘든 경우가 종종 있을 것이다. 나같은 경우 예전에 내가 작성한 코드에서 이슈가 나서 다시 보았을 때 로직 파악이 쉽지 않아서 빠르게 처리하지 못한 경험이 있었다.

그리고 다른 개발자들과 함께 일하는것이 대부분이고, 코드를 작성하는 것보다 읽는 작업이 더 많다.

그래서 코드의 가독성은 매우 중요하다. 

변수, 메서드 클래스 등 코드 한줄을 작성할 때도 이름만으로 어떤 레이어에서 어떤 역할을 하고 있는지 명확하게 나타내려고 하는 습관을 들이는데 노력을 기울여야 한다.

common, util 같은 넓은 범위의 역할 보단 좁은 범위를 나타내는 역할을 맡을 수 있는 네이밍을 추천한다.

레이어드 아키텍처

https://velog.io/@gmtmoney2357/%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%EB%A0%88%EC%9D%B4%EC%96%B4%EB%93%9C-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98Layered-architecture

 

레이어드 아키텍처는 유사한 기능들을 같은 계층으로 묶어 관리하는 방식의 아키텍처다.

  • 의존성 방향이 상위 계층에서 하위 계층의 단방향 흐름을 유지한다. 
    • Business layer에선 import문엔 Presentation layer의 클래스를 알면 안된다.
  • 엄밀히 따지면, Presentation layer에선 Business layer를 생략하고 Persistence layer을 직접 의존하면 안되지만 실무에선 필요시 유동적으로 할 수 있다.
  • 단점은 의존성 최상위 계층이 database layer이기 때문에 DB 중심의 설계로 하게 된다. 즉, 비즈니스 로직이 핵심이 아니고, 보호받지도 못한다.
  • DIP와 OCP를 만족시키지 못한다.
    • DIP  : 상위 레이어가 하위 레이어에 접근시 구체적인 구현이 아닌 추상화 인터페이스에 접근할 수 있다. 
    • OCP: 새로운 기능을 추가하거나 기존 기능을 확장시 어려울 수 있다. 왜냐하면 비즈니스 로직이 Service에 모두 뭉쳐져 있기 때문이다.

헥사고날 아키텍처

https://mesh.dev/20210910-dev-notes-007-hexagonal-architecture/

헥사고날 아키텍처는 모든 외부와의 통신을 인터페이스로 추상화하여 비즈니스 로직 안에 외부 코드나 로직의 주입을 막는 아키텍처다.

  • 애플리케이션의 핵심은 비즈니스 로직이고, 도메인을 순수하게 유지할 수 있다.
  • 데이터 계층 및 API 계층이 비즈니스 로직을 의존한다.
    • 어댑터 & 포트 패턴이라고도 불린다.
    • 외부 인프라는 포트를 통해서 접근해야 한다.
    • 다양한 외부 인터 페이스 (API, MQ, WebSocket 등)에 동일한 비즈니스 로직을 전달할 수 있도록 하는 아키텍처
  • 장점은 가이드 라인이 명확하다.
  • 단점은 변환 로직이 필요하고 규칙들이 엄하다.
  • DIP와 OCP를 만족시킨다.
    • DIP  : 포트라는 추상화된 인터페이스를 통해 애플리케이션 레이어에 접근한다.
    • OCP: 기능 확장하거나 변경시 어댑터를 추가하거나 변경 하면 된다.

클린 아키텍처

https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html

클린 아키텍처는 관심사에 따라 계층을 나누고, 도메인을 중심으로 설계하며 외부세계로 부터 도메인을 격리시키는 아키텍처다.

  • 애플리케이션의 핵심은 비즈니스 로직
  • 데이터 계층 및 API 계층이 비즈니스로직을 의존 (UseCase & Port 패턴)
    • use cases는 인터페이스, 기능 단위로 보면 된다.
      • 포인트 충전, 포인트 사용
  • 도메인 중심적인 고수준의 관심사 분리
  • jpa 엔티티와 도메인 엔티티를 분리해야 한다. (헥사고날 아키텍처도 마찬가지)
  • DIP와 OCP를 만족시킨다.
    • DIP  : 추상화된 인터페이스를 통해 애플리케이션 레이어에 접근한다.
    • OCP: 기능 확장하거나 변경시 인터페이스의 구현체를를 추가하거나 변경 하면 된다.

클린 + 레이어드 아키텍처

https://hanghae99.spartacodingclub.kr/plus/be?utm_source=google&utm_medium=bs&utm_campaign=hhplus&utm_content=brand&utm_term=%ED%95%AD%ED%95%B4%ED%94%8C%EB%9F%AC%EC%8A%A4&gcl_keyword=%ED%95%AD%ED%95%B4%ED%94%8C%EB%9F%AC%EC%8A%A4&gcl_network=g&gad_source=1&gclid=CjwKCAjw7NmzBhBLEiwAxrHQ-cRiDNjsG6tPHWjRRnaM1qMYP1yZFEKDKSBqAir8u9AGgEZicyyjRhoC6HgQAvD_BwE

Presentation <-> Business는 직접 의존하고, Businiss <-> DataSource는 DIP를 적용하는 아키텍처다.

  • 애플리케이션의 핵심은 비즈니스 로직
  • 데이터 계층 및 API 계층이 비즈니스 로직을 의존 
  • 도메인 중심적인 계층 아키텍처
  • Business에서 기능별(Usecase)로 나눈다.
  • Business <-> Datasource 계층 사이에 계층을 하나더 추가할 수 있다.
    • CQRS를 위한 -Reader, -Writer
    • Datasource에만 의존하는 implementation 계층
  • DIP와 OCP를 만족시킨다.
    • DIP  : 비즈니스와 DataSource 계층에서 DataSource의 의존성 방향이 역전되어 적용되었다.
    • OCP: 비즈니스와 DataSource 계층에 DIP가 적용되어 자연스레 OCP도 적용되었다. 
      • ORM 에서 Mybatis 추가시 오른쪽 그림의 ORM Repository에서 Mybatis Repository를 추가하고 인터페이스를 구현받으면 된다.

클린 코드에서 추구하는 것

  • 읽기 쉽고 단순한 코드
    • 코드는 누구나 쉽게 읽을 수 있어야 하며, 좁은 범위의 책임을 가질 것
  • 의존성 격리
    • 모듈간 미치는 영향을 최소화 하기 위한 의존성 격리
  • 추상화
    • 명세와 구현을 적절히 분리 할 것
    • 적절한 추상화가 중요하다. 많으면 추적이 힘들고 적으면 변경에 영향을 받는다.
  • 중복성 최소화
    • 중복된 코드는 지양할것
    • 하지만 코드가 2번만 중복되는 걸 private으로 빼도 괜찮을지? 같은 고민도 해볼 것
  • 변경 영향을 최소화 할 수 있는 코드 작성
    • 코드 구성의 변경 영향이 작아야 코드를 오래 사용할 수 있다.

 

현재 항해 플러스 백엔드 코스 6기 모집중입니다.
항해플러스 관련해서 문의 주실 내용 있으시면 이메일 혹은 댓글로 편하게 문의주세요!!
지원시 추천 코드 입력 한번 부탁드립니다!!

 

추천코드
HHPGS0858

https://hanghae99.spartacodingclub.kr/plus/be