반응형

헥사고날 아키텍처를 보고 난 뒤 내가 느낀 점은

SOLID 에서 I 강조한 아키텍처라고 생각했다. (I Inversion of Control 의존성 역전)

 

헥사고날 아키텍처는 레이어드 아키텍처의 일반적인 의존성 방향을 해결하기 위해 고안된 아키텍처이다.

아래 그림과 같다. 각각의 어댑터 구간이 포트를 통해 유스케이스와 연결되어 최종적으로 엔티티에 결합되는 구조이다.

 

 

헥사고날 아키텍처가 포트&어댑터 패턴이라고 불리는 이유가 여기있다.

어플리케이션 코어와 어댑터 간의 통신이 가능하려면 애플리케이션 코어가 각각의 포트를 제공한다. driving 어댑터에게는 포트가 코어에 있는 유즈케이스 클래스에 의해 구현되어 호출되는 인터페이스가 되며, driven 어댑터에게는 포트가 어댑터에 의해 구현되고 코어에 의해 호출되는 인터페이스가 된다.

 

포트라는 인터페이스를 통해 내부와 외부의 경계를 나누는 것을 볼 수 있으며, 의존성 방향을 내부와 외부로 나눈 것도 하나의 특징이다. 이 헥사고날 아키텍처를 현업에서 가장 많이 쓰이는 Spring 에서 살펴보자.

 

일단 소스코드 구조 상으로는 아래와 같다.

 

 

유스케이스 (인터페이스, 구현체는 Service)

 

출처 : 백문이불여일타 (tistory.com)

 

- 모델 상태를 조작한다

- 출력을 반환한다

- 비즈니스 규칙을 검증한다

- 웹으로부터 입력을 받는다

 

인터페이스로 존재하며, 구현체 Service 입력 포트와 출력 포트를 가지고 있다.

LoadEventPort, RecordEventPort 라는 어탭터의 출력 포트를 통해 out/persistenceAdapter 통신하게 된다.

 

어댑터

 어댑터 (WebAdapter 어노테이션, Controller)

 

출처 : 백문이불여일타 (tistory.com)

 

- HTTP 요청을 자바 객체로 매핑하기

- 권한을 검사하기

- 입력 유효성 검증하기

- 입력을 유스케이스의 입력 모델로 매핑하기

- 유즈케이스 호출하기

- 유즈케이스의 출력을 HTTP로 매핑하기

- HTTP 응답을 반환하기

 

영속성 어댑터

 

출처 : 백문이불여일타 (tistory.com)

 

- 입력을 받는다

- 입력을 데이터베이스 포맷으로 매핑한다

- 입력을 데이터베이스로 보낸다

- 데이터베이스 출력을 애플리케이션 포맷으로 매핑한다

- 출력을 반환한다

 

Spring 에서 헥사고날 아키텍처의 흐름을 정리하면 다음과 같다.

Controller(어댑터) -> UseCase(인터페이스, 설마 Port ?) -> Service(구현) -> Port(인터페이스) -> Adapter(구현) -> Repository

 

원래 그림대로라면 Controller UseCase 사이에 Port 존재해야 되는 것이 맞지 않나라고 생각했다. 아니 호출해야 되는 것이 맞다. 그런데 아래 내가 공부한 출처들에서 모두 생략하고 있다. UseCase 자체가 이미 인터페이스이기 때문에 의존성 역전이 이미 되어 있는 상태이니까 생략한 것이 아닐까라고 추측했다. 결국엔 포트를 둔다는 서로 다른 영역을 나누기 위한 경계 , 인터페이스로 의존성 역전을 한다는 의미일 것이니 말이다.

 

그런데, 그림을 보면 실체화하는 위치가 다르다. Driving 어댑터 쪽은 UseCase 실체화이고, Driven 어댑터 쪽은 Adapter 실체화이다. 구조를 Spring 구조와 비교해보면 UseCase Input Port 라는 것을 있고 Service 사실상 그림에서 UseCase 되는 것이다. 혼동이 있는 여지가 있지만, Spring 에서는 전통적으로 방식으로 설계해왔기 때문에 Input Port 사라진 것처럼 보인 것이었다.

 

출처

Hexagonal Architecture with Java and Spring (reflectoring.io)

백문이불여일타 (tistory.com) 

반응형

'독후감 > 교양' 카테고리의 다른 글

[TDD] 의식적인 연습으로 TDD, 리팩토링 연습하기  (0) 2022.04.25
반응형

오늘의 공부 영상은 아래 영상입니다. 원본 영상은 아래 링크를 참조해주세요~

 

 

TDDTest Driven Development 의 약자로 "테스트 주도 개발"이라고 한다. 작은 단위의 테스트를 먼저 작성하고 그 테스트를 통과하는 코드를 지속적으로 추가하면서 짧게 개발하는 애자일 방법론 중 하나이다.

 

TDD 사이클

 

TDD 사이클은 위 그림과 같다. INITAL TEST 단계부터 시작해서 REFACTOR CYCLE 까지 순차적으로 반복 수행한다.

INITAL TEST 단계에서는 실패하는 테스트 코드를 먼저 작성한다. 다음 단계 가기 전까지 실제 로직에 들어가는 코드를 작성하면 안 된다. CODE 단계에서는 테스트 코드를 성공시키기 위한 실제 로직을 작성한다. REFACTOR CYCLE 단계에서는 중복 코드 제거, 일반화 등 리펙토링을 수행한다.

 

먼저 실패하는 테스트 코드를 작성하는 것은 어렵게 느껴지지 않는다. 요구사항에 주어진 입력과 출력의 경계라던지, 요구사항에 주어진 규칙에 반대되는 코드들을 작성하면 된다. 그런데 막상 해보면 알고리즘 문제에서 주어지는 통합환경에서의 테스트 정도다.

 

이 정도의 테스트만 해도 될까? 더 해야 되는 테스트가 있을까? 그런 생각을 하던 찰나에 위 영상을 보게 되었다.

영상에서는 처음부터 TDD 를 의식하지 말고 아래와 같은 규칙을 만들면서 코딩 연습을 해보라고 권장하고 있다.

 

코드 컨벤션을 지키면서 프로그래밍한다.

(자바의 경우, Google Java Style Guide)

한 메서드에 오직 한 단계의 들여쓰기만 한다.

함수 또는 메서드가 한 가지 일만 할 수 있도록 작게 만든다.

else 예약어를 쓰지 않는다.

모든 원시값과 문자열을 포장한다.

한 줄에 점을 하나만 찍는다.

불필요하게 공백 라인을 만들지 않는다.

공백 라인을 띄우는 것도 의미있게 띄우자.

줄여쓰지 않는다.(축약 금지)

모든 엔티티를 작게 유지한다.

3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다.

일급 컬렉션을 쓴다.

객체에서 데이터를 꺼내지 말고 객체에 메세지를 보내라.

Getter/Setter/Property 를 쓰지 않는다.

메서드(함수)에서 이상적인 인자 개수는 0개이다. 인자의 갯수를 3개 이하로 줄여라.

 

위 규칙들을 지키면서 코딩하게 되면, 자연스레 메서드와 클래스가 작은 단위로 쪼개지고 각 단위 별 테스트가 가능해진다. 마지막 문장은 클린 코드에서 본 문장이었는데 억지스러운 문장처럼 보이지만 실제로 된다. 저 내용 말고도 더 많은 내용들이 있겠지만, 오늘부터 위 내용을 반드시 지키면서 코딩해보려고 한다.

 

끝으로 영상 마지막 부분에 누가 강사님께 질문을 했는데 내가 직접 답변해보면서 마무리하고자 한다.

 

Q . TDD 로 개발하다보면 재사용성은 좋지만 같은 기능을 중복되서 작성하거나, 성능에 이슈를 가져오는 코드가 생길 수 있는데 어떻게 생각하시나요?

 

A . 객체지향으로 설계하다 보면 간혹 기능이 중복되는 코드들이 존재하는데 나중에 리팩토링 단계에서 합성이나 프록시 패턴으로 반복되는 구간을 함께 운영하면 좋을 것 같다. 테스트를 용이하게 작성하는 것이 제일 중요하다. 그 후 성능에 가져오는 코드들만 모아 다시 리팩토링하면 좋지 않을까 생각한다.

반응형

'독후감 > 교양' 카테고리의 다른 글

[아키텍처] 헥사고날 아키텍처  (0) 2022.08.08

+ Recent posts