5장. 웹 어댑터 구현하기

Seungjae·2022년 6월 9일
0

우아한 스터디

목록 보기
6/10
  • 이번장은 웹 인터페이스를 제공하는 어댑터의 구현 방법을 알아본다.

의존성 역전


  • 웹 어댑터는 외부로부터 요청을 받아 애플리케이션 코어를 호출한다.

  • 제어 흐름은 웹 어댑터에 있는 컨트롤러에서 애플리케이션 계층에 있는 서비스로 흐른다.

  • 애플리케이션 계층은 웹 어댑터가 통신할 수 있는 특정 포트를 제공한다.

  • 서비스는 이 포트를 구현하고, 웹 어댑터는 포트를 호출한다.

  • 제어 흐름을 봐서는 웹 어댑터가 유스케이스를 직접 호출해도 되는데, 왜 굳이..? 포트를..?

    • 코어가 외부 세계와 통신할 수 있는 곳에 대한 명세가 포트이기 때문! → 이 자체로도 애플리케이션이 커질수록 큰 기능이 된다!
    • 외부와 어떤 통신이 일어나고 있는지 정확히 인지 가능
    • 유지보수하는 엔지니어에게 큰 정보다!
  • 또한 상호작용이 많이 일어나는 애플리케이션에서! [웹 소켓]

    • 실시간 데이터를 사용자의 브라우저로 보내야한다.
    • 코어에서 이러한 실시간 데이터를 어떻게 웹 어댑터로 보내고, 웹 어댑터는 이 데이터를 어떻게 사용자의 브라우저로 전송할까?

  • 위 그림처럼 애플리케이션이 웹 어댑터에 능동적으로 알림을 줘야한다면, 의존성을 올바른 방향으로 유지하기 위해 아웃고잉 포트를 통과해야한다! [웹 → 서비스로 바로 포트 없이 의존하고 있었다면 의존성이 순환하게 된다!]

  • 이때 아웃고잉 포트를 구현하기 때문에, 웹 어댑터는 인커밍 어댑터인 동시에 아웃고잉 어댑터가 된다.

웹 어댑터의 책임


  1. HTTP 요청을 자바 객체로 매핑
  2. 권한 검사
  3. 입력 유효성 검증
  4. 입력을 유스케이스의 입력 모델로 매핑
  5. 유스케이스 호출
  6. 유스케이스의 출력을 HTTP로 매핑
  7. HTTP 응답을 반환
  • 웹 어댑터 입력 모델은 유스케이스 입력 모델과 구조나 의미가 완전히 다를 수 있다! → 또 다른 유효성 검증을 수행해야 한다.

    • 웹 어댑터의 입력 모델을 유스케이스의 입력 모델로 변환할 수 있다는 것을 검증해야한다!
  • 웹 어댑터의 책임이 매우 많아보인다. 하지만 이 책임들은 애플리케이션 계층이 신경 쓰면 안되는 것들이다!

  • HTTP와 관련된 것이 애플리케이션 계층으로 침투하면 안 된다.

    • 만약 침투하면?
      • HTTP를 사용하지 않는 또 다른 인커밍 어댑터의 요청에 대해 동일한 도메인 로직을 수행할 수 있는 선택지가 사라지게 된다!
      • 좋은 아키텍처에서는 선택의 여지를 남겨둔다.
  • 웹 어댑터와 애플리케이션 계층 간의 이 같은 경계는 도메인과 애플리케이션 계층부터 개발하기 시작하면 자연스럽게 생긴다.

컨트롤러 나누기


  • 웹 어댑터 → 1개 이상의 클래스로 구성 가능!

    • 단, 같은 패키지 수준! (같은 소속이라는 것을 표현)
  • 컨트롤러는 얼마나 만들어야하는가?

    • 너무 적은 것보다는 너무 많은게 낫다!
    • 가능한 한 좁고 다른 컨트롤러와 가능한 한 적게 공유하는 웹 어댑터 조각을 구현해야한다!
    • 즉, 컨트롤러도 쪼갤 수 있으면 쪼개라!
  • 클래스마다 코드는 적을수록 좋다!

    • 클래스의 코드가 많을 수록 그 코드의 의미를 정확하게 파악하는 난이도가 매우 높아진다.
  • 컨트롤러에 코드가 많다면 그에 해당하는 테스트 코드도 많아지게 된다!

    • 특정 프로덕션 코드에 해당하는 테스트 코드를 찾기 쉬워야하는데, 클래스가 작을수록 더 찾기 쉽다!
  • 모든 연산을 단일 컨트롤러에 모아놓으면...

    • 데이터 구조의 재활용을 촉진한다..!
    • 즉 모델 클래스를 공유할 확률이 높아진다.
    • 해당 연산에 필요없는 모델 클래스를 사용함으로써 혼란이 생길 수 있다.
  • 별도의 패키지 안에, 별도의 컨트롤러를 만들자! → 메서드와 클래스명을 유스케이스를 최대한 반영해서!

  • 이렇게 별도 컨트롤러를 만들고, 그에 대한 전용 클래스들이 생기게 되면!

    • 패키지 private으로 인해 모델이 다른 곳에서 재사용되지 않는다!
    • 컨트롤러끼리 모델을 공유할 수는 있지만 세부 패키지를 구분함으로써, 공유하기 전에 한번 더 생각하게 된다!
  • 이렇게 나누는 스타일의 또 다른 장점 → 서로 다른 연산에 대한 동시 작업이 쉬워진다!

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


  • 웹 어댑터를 구현할 때

    • HTTP 요청을 애플리케이션의 유스케이스에 대한 메서드 호출로 변환하고
    • 결과를 HTTP로 변환한다.
    • 이때 어떤 도메인 로직도 수행하지 않는 어댑터를 만든다.
  • 애플리케이션 계층은 HTTP에 대한 상세 정보를 노출시키지 않도록 HTTP와 관련된 작업을 해서는 안 된다!

  • 웹 컨트롤러를 나눌 때, 모델을 공유하지 않는 여러 작은 클래스들을 만드는 것을 두려워해서는 안 된다!

    • 작은 클래스들은 더 파악하기 쉽고, 테스트하기 쉽고, 동시 작업을 지원한다!
  • 물론 Cost가 더 있지만, 유지보수 측면에서 큰 이득이 있다!

profile
코드 품질의 중요성을 아는 개발자 👋🏻

0개의 댓글

관련 채용 정보