김동형수 개발기

만들면서 배우는 클린 아키텍처 - 05 정리 본문

책 스터디/[완료] 만들면서 배우는 클린아키텍처

만들면서 배우는 클린 아키텍처 - 05 정리

김동형수 2022. 4. 12. 01:09

웹 어댑터 구현하기

오늘날의 애플리케이션은 대부분 웹 인터페이스 같은 것을 제공한다. 웹브라우저와 상호작용하는 UI, HTTP API가 여기에 해당한다.

클린아키텍처에서 외부 세계와의 모든 커뮤니케이션은 어댑터를 통해서 이뤄진다.


의존성 역전

웹 어댑터는 외부로부터 요청을 받아 애플리케이션 코어를 호출하고 무슨 일을 해야 할지 알려준다. 이떄 제어의 흐름은 컨트롤러(웹 어댑터) -> 서비스(애플리케이션 계층) 으로 흐른다.

 

애플리케이션 계층은 웹 어댑터가 통신할 수 있는 특정 포트를 제공한다. 서비스에서 포트 인터페이스를 구현하고 컨트롤러에선 포트 인터페이스의 의존성 주입을 통해 호출할 수 있다.

 

직접호출할 수 있지만, 애플리케이션 코어가 외부와 통신할 수 있는 곳에 대한 명세가 포트이기 때문이다.

 

서비스를 직접호출하게 되면 헥사고날 아키텍처의 육각형 구조와 맞지 않게된다.
포트에서 외부와 통신하면서 필요한 전처리 / 후처리를 하게 되면 책임이 나눠져서 서비스는 비즈니스 로직에 대한 책임만 맡고, 포트는 외부와 통신(?)하면서 필요한 처리에 책임만 맡게 되면 될 것 같다.

추가해야하는 클래스의 개수가 많고 코드량이 증가함에 따라 컨트롤러에서 서비스를 직접 호출하는 지름길을 이용하고 싶은 생각이 들 것 같다.

 


웹 어댑터의 책임

  1. HTTP 요청을 자바 객체로 매핑
  2. 권한 검사
  3. 입력 유효성 검증
  4. 입력을 유스케이스의 입력 모델로 매핑
  5. 유스케이스 호출
  6. 유스케이스의 출력을 HTTP로 매핑
  7. HTTP 응답을 반환

위 순서가 샘플코드인 BuckPal의 REST API가 호출될 때 일련의 과정을 나열한 것 같다.

 

웹 어댑터 역할

  • URL, 경로, HTTP 메서드, 콘텐츠 타입 등 특정 기준을 만족하는 HTTP 요청 수신
  • HTTP 요청 파라메터와 콘텐츠를 객체로 역 직렬화
  • 인증, 권한부여에 대한 실패 처리
  • 역직렬화 된 객체의 유효성 검사
    • 유스케이스의 입력모델에서 하는 유효성 검사와는 다른 이야기다.
  • 웹 어댑터의 입력 모델 -> 유스케이스 입력 모델 변환 가능성 검증

웹 어댑터에 책임이 상당히 많다. 이 책임들은 애플리케이션 계층에서는 신경쓰지 않아도 되는 내용이다.

유스케이스를 먼저 구현하고 포트, 웹 어댑터를 구현하면 경계를 흐리게 만들 유혹에 빠지지 않을 수 있다고 저자는 말한다.


컨트롤러 나누기

컨트롤러가 가능한 좁고 다른 컨트롤러와 가능한 한 적게 공유하는 웹 어댑터 조각을 구현해야 한다.

 

 

 

위의 샘플코드를 살펴보면 모든 내용이 하나의 컨트롤러에 모여 있으며 괜찮아 보인다. 하지만 단점이 있다.

 

1. 클래스의 코드의 양은 적을수록 좋다.

   클래스에 코드의 양이 많다면,기존코드에서 추가된 코드에 대한 내용을 파악하기 어려워진다.

2. 테스트코드 또한 마찬가지다. 코드가 길어지면 테스트코드를 찾는데 어려움이 있다.

3. 데이터구조의 재활용, 필요없는 필드가 들어있어서 응답이 명확하지 않아서 요청하는 입장에서 헷갈릴 수 있다.

 

AccountController와는 다르게 목적성에 맞게 컨트롤러를 분리해서 코드의 양을 줄였다.

데이터구조의 재활용을 하지 않고 웹 어댑터마다 다른 형태의 모델을 사용해서 요청/응답을 명확하게 했다.

 

패키지와 컨트롤러를 분리하더라도 모델 객체를 공유할 수 있지만, package-private 한 구조기 때문에 다른 패키지의 모델을 사용하려면 import를 해야하는데 이때 좀 더 신중하게 사용할 수 있다. 높은 확률로 모델 클래스를 만들 것이다.

 

그리고 컨트롤러명과 서비스명에 대해서도 잘 생각해봐야 한다. 비슷한 뉘양스의 단어라도 그 의미를 메서드 명만으로도 알 수 있게끔 실제 목적에 맞는 단어를 선택해서 작성하면 좋겠다고 저자는 말한다.

 

이렇게 나누게되면 결국 여러 개발자가 다른 유스케이스에 대해서 개발할 때 형상관리도구에서 소스코드가 충돌날 확률이 줄어들게 된다.

 


유지보수 가능한 소프트웨어를 만드는 데 어떻게 도움이 될까?

웹 어댑터를 구현할 때는 HTTP 요청, 애플리케이션의 유스케이스 메서드 호출하고 그 결과 값을 HTTP로 반환하는 작업을 수행하도록 구현한다. 이는 어떠한 도메인 로직도 수행하지 않는다.

 

애플리케이션 계층을 구현할 때는 HTTP에 대한 상세 정보를 노출시키지 않도록 HTTP와 관련된 작업을 해서는 안 된다. 이렇게 하면 필요할 경우 웹 어댑터를 다른 어댑터로 쉽게 교체할 수 없다.

 

웹 컨트롤러를 나눌 때는 모델을 공유하지 않는 여러 작은 클래스로 만들어야 한다. 이는 파악이 쉽고, 테스트가 쉬우며, 동시 작업을 할 경우 형상관리도구에서 충돌이 일어나지 않도록 해준다. 기존의 방법보단 코드의 양과 공수가 더 들겠지만 유지보수할때 클린아키텍처의 빛을 발할 것이라 저자는 말한다.

 

한줄 정리 계층별 책임의 경계선을 명확히하고 컨트롤러는 작은 단위로 해서 유지보수성을 높이자.
Comments