You will be fine

<Architecture> 헥사고날 아키텍처 구조로 변경해보기 예제

by BFine
반응형

팀내 스터디로 만들면서 배우는 클릭아키텍쳐를 읽고 실습한 내용이 있는데 나중에 기억안날 수 있으니 적어두어야겠다.!

아키텍처 빼고도 좋은 내용이 많고 책도 얇아서 한번쯤은 읽어보면 좋은 책인것 같다!

참고 & 출처 : http://www.yes24.com/Product/Goods/105138479

 

만들면서 배우는 클린 아키텍처 - YES24

우리 모두는 낮은 개발 비용으로 유연하고 적응이 쉬운 소프트웨어 아키텍처를 구축하고자 한다. 그러나 불합리한 기한과 쉬워보이는 지름길은 이러한 아키텍처를 구축하는 것을 매우 어렵게

www.yes24.com

 

가.  계층형 아키텍처 예제

2022.04.02 - [공부/GraphQL] - 4. 동물원 예제 만들기 with Spring Boot

 

<GraphQL> 4. 동물원 예제 만들기 with Spring Boot

가. 개요 a. 활용을 잘 할 수 있을까? - 보통 어떻게 쓰는지 궁금해서 깃허브 찾아보니 Spring Boot grahpql 관련 레포지토리들이 대부분 기본 예제 뿐이고 스타일도 다른것 같다. - 어떻게 하면 graphql의

willbfine.tistory.com

지난 번에 GrahpQL 공부하면서 만들어본 동물원 예제를 헥사고날 아키텍처로 변경 해보았다.

 

 a.  패키지 구조

  -  일단 GrahpQL 구조에서 Rest 형태로 바꾸었는데 약간 좀 틀어지긴 했지만 진행하는데는 크게 문제는 없었던 것 같다.

편의상 Controller에 Repository를 사용했었다 (예제니까..)

   -  의존성의 방향은 대략 위 이미지처럼 되어있다. 

 

 b.  계층형 아키텍처의 단점

  -  대부분 비슷하게 해당 구조로 실무에서도 많이 사용하고 있는것 같은데 이 구조의 단점은 무엇이 있을지  읽어보고난 뒤에 느낀점을 적어보았다.

    1. Controller에서 호출하는 Service 하나 하나에 너무 많은 기능이 들어가는데 찾기가 어렵다.

        => 예를들어 AnimalService 있다고 한다면 Animal 관련되어있으면 기능을 여기에 다 때려박게 되고 하나의 기능을 찾기 어렵다.

    2. 패키지 의존성이 심해진다.

        => 모든 상황에서 중복코드를 줄이기 위한 재사용은 좋지 않다라고 생각하는데  계층형 구조에서는 확실히 패키지 구분없이 사용되는게 많아지는 것 같고

            도메인 A를 관련된 부분을 수정했는데 도메인 B까지 영향이 가는 경우가 한번쯤은 있지 않을까 싶다.. 

 

 c. 예제 기능들 

  -  동물(Animal)           -  직원(Employee)        -  매핑(EmployeeAnimal)

     -  동물 등록                 - 직원 등록                    - 동물 <-> 사육사(직원) 담당을 연결

     -  단건 조회                  - 전체 조회                    => 동물 - 사육사의 모델 연관관계는 다대다 관계이다!

     -  전체 조회

  

나.  헥사고날 아키텍처 구성요소

 a.  Adapter

  -  헥사고날 아키텍처에서는 사용자 인터페이스나 저장소(DB) 는 비지니스 로직으로부터 분리해야하는 요소로 보고있다.

  -  여기서 Adapter는 프레젠테이션 계층(사용자 인터페이스)에 대한 외부 통신을 담당한다. 

      - in    : 사용자 인터페이스 (REST API, Grahphql 등)

      - out : 데이터베이스 관련 (RDB, Redis + ORM, JPA) 

 

 b. UseCase

  -  인커밍 Adapter로 부터 입력받는 역할은 하고 인터페이스이므로  비즈니스 로직을 구현하는 Serivce 클래스에서 해당 기능을 구현하는 형태이다.   

  -  UseCase의 명세(메서드)는 최대한 작은 범위로 구성해야하며 입력 유효성 검증은 하지 않는다.(비지니스 규칙만 검증)

 

 c. Port

  - 아웃고잉 Adapter과 연결하는 역할을 하고 마찬가지로 인터페이스인데 여기는 데이터소스 계층과 연결한다.

 

다.  헥사고날 아키텍처로 변경하기

 a.  변경 패키지 구조

  -  의존성의 방향은 대략적으로 아래와 같다. (완전매핑 전략으로 구현해보았다. Domain =/= Entity)

 

 b. 기능 흐름 살펴보기

  -  동물 조회 기능의 흐름을 패키지 구조랑 같이 따라가 보면

 1.  Adpater(in) : GetAnimalUseCase로 부터 Animal을 조회

   - Controller가 있고 기능별로 나눠둔 UseCase를 사용해서 기능을 처리한다.  한다.

   - 여기서 고민이 들었던 부분은 dto의 위치였다. 처음에는 해당 패키지 하위에 만들려고 했는데 그렇게 하면 UseCase를 구현한 Service에 rest 패키지

     의존성이 생겨서 고민하다 호출하는 쪽에 만들어두면 좋겠다는 생각이 들어 UseCase가 있는 패키지 하위에 dto를 만들었다.

      => 책을 다시보니 Adapter의 dto를 만들고 application의 dto도 만들어서 변환하는 시점에 입력 유효성 검증을 하도록 되어있었다.. 

깔끔하다..!

 2. application.port.in UseCase & application.serivce Service : 요청받은 Animal ID들로 loadAnimalPort를 통해 Animal을 조회한다.

   - adapter에서 흘러들어온 요청이 UseCase의 메서드를 호출한다. UseCase는 Service에서 구현한다.

  - Service에서는 port.out 패키지에 있는  Port(interface) 를 이용해서 외부(db, cache 등등) 데이터 요청 & 처리를 한다. 

  - 여기서 느꼈던 부분이 여러 UseCase가 하나의 Service에 구현이 되지만 기존 계층형 구조와는 다르게 이 기능이 어떤 요구사항인지를 인터페이스로

     올라가서 UseCase의 이름 보면 바로 알수있어서 확실히 좋다라는 생각이 들었다.

 3. port & Adapter(out) :  비즈니스계층으로 부터 전달된 Animal ID를 가지고 AnimalRepository를 이용하여 실제 저장된 데이터(Animal)를 가져온다.  

   - out 에 있는 Port 들을 사용하여 Adapter 계층(아웃고잉)과 연결하고 있다.

   -  여기서 잘못한 부분은 Animal은 도메인인데 Adapter 게층에서 사용되고 있다.. 이렇게 되면 도메인로직을 쓴다던지 하는 경우에

       강한 의존성이 발생할 것으로 보인다..  
      => 다시 생각해보면 이부분까지 dto를 사용했을경우에 완벽하게 비즈니스 계층과 외부 계층이 분리할 수 있다는 것을 알 수 있었다..!

 

 c.  해보고 나서 느낀점

  -  글쓰기 전에는 별로가 70% 정도 였는데 글쓰면서 다시 만들었던거 살펴보면서 정리하다보니 괜찮다가 70% 까지 올라온것 같다.

  -  비즈니스 계층과의 외부연결과의 의존성 분리하는 측면에서 많은 공부가 된것 같아서 좋았고 계층형 아키텍처에만 너무 익숙해져 있었구나 생각도 들었다.  

  -  예제는 단일모듈로만 했지만 멀티모듈로 구현해본다면 좀 더 명확하게 구분지을수 있을 것 같은 느낌이 들었다.

  -  최근에 헥사고날 아키텍처라는 말이 자주 들려서 요렇게 한번 공부해보았는데 주의할점은 요즘 핫(?)하다고 해서 적용해야지 하는 것은 아닌 것 같다.

     물론 예제지만 이렇게 규모가 작은 것에 해봤는데도 클래스나 인터페이스가 많이 늘어나고 dto 변환이라던지 유지보수 해야할 포인트가 훨씬

     늘어나지 않을까 라는 생각이 들었다. 규모나 도메인이나 사용하는 기술들을 먼저 정리하고 잘 녹아들수 있는지 판단한 이후에 적용하는 것이 좋을것 같다.!

반응형

블로그의 정보

57개월 BackEnd

BFine

활동하기