Introduce

Technical Debt

  • 소프트웨어 내에 불필요한 복잡성이 얼마나 존재하는지를 설명하는데 사용된다.
  • 이런 불필요한 복잡성을 cruft라고 한다.
  • 명확한 패턴이 없는 코드, 이해하기 어려운 코드, 그저 덧대는 코드는 기술 부채를 키울 여지를 남긴다.
  • 물론 기술부채를 무조건 없애야 하는 것은 아니다. 그러나 이는 이후 문제 해결에 있어서 어색한 해결을 낳는다.
  • 이는 또다른 쓸 데 없는 복잡성을 낳고 이해하기 어려운 코드를 만든다.
  • 결국 부채가 쌓이면 더 이상 손 쓸 수 없게 된다.

Hexagonal

UI/ DB 없이 동작하게 만들면 애플리케이션에 대해서 자동화된 회귀 테스트도, DB 없이도 동작한다. 그리고 어떤 사용자 개입 없이도 애플리케이션을 연결할 수 있다.

  • 알리스테어 콕번이 만든 헥사고날 아키텍쳐의 주된 아이디어 중 하나는 ‘비즈니스 코드를 기술 코드로부터 분리하는 것’이다.
  • 기술 측면이 비즈니스 측면에 의존하는지 확인하고 비즈니스 측면이 비즈니스 목표를 달성하는 데 사용되는 기술에 대한 우려 없이 발전할 수 있게 해야 한다.
  • 즉, 비즈니스 내용을 기술적 내용과 뒤섞어 일부러 뒤로 미룬 기술적 내용을 변경하기 어렵게 두지 않는 것을 기본으로 한다.

Domain Hexagon

  • SW가 해결해야하는 핵심 문제를 설명하는 요소들을 결합한다.
  • DDD의 개념을 다수 차용한다. 엔티티, 값 객체 등 말이다.
  • 도메인 헥사곤은 비즈니스 규칙을 정하고 이를 통해서 문제를 해결하는 과정이 담긴다.
  • 실 세계 문제를 이해하고 모델링하는 활동을 나타낸다.
  • 도메인 헥사곤 안에는 중요한 비즈니스 데이터와 규칙에 관련된 엔티티들이 있다.
  • 표현력을 위해 값 객체 등을 사용한 ‘풍부한 도메인 객체’를 목표로 한다.

엔티티

  • 표현력이 있는 코드를 작성하는 데 도움을 준다.
  • 식별자가 있다.
  • 도메인 모델을 표현하며, 이에 대한 비즈니스 로직을 캡슐화하고 있다.
  • 일종의 activeRecord 패턴을 의미한다.

값 객체

  • 엔티티의 부족한 표현력을 채워준다.
  • 항상 값은 변경할 수 없어야 하고, 필요하다면 아예 해당 객체를 대체하는 식으로 구성되어야만 한다.

Application Hexagon

  • 도메인 헥사곤에 정의된 비즈니스 규칙을 사용하여 전체적인 처리를 담당한다.
  • 비즈니스 측면과 기술 측면 사이에 있으며 양쪽을 중재하는 역할을 한다.
  • 애플리케이션 특화 작업을 추상적으로 처리하는 곳이다.
  • 도메인 비즈니스 규칙에 기반한 SW 사용자의 의도와 기능을 표현한다.
  • UseCase, InputPort, OutputPort를 기반으로 고수준의 애플리케이션 핵사곤 구조를 보여준다.

UseCase

  • 도메인 제약 사항을 지원하기 위해서 시스템의 동작을 SW 영역 내의 존재하는 애플리케이션 특화 오퍼레이션을 통해서 나타낸다.
  • SW가 할 수 있는 것을 표현하는 인터페이스로 정의된 추상화로 나타낸다.

InputPort

  • useCase를 구현하는 역할을 한다.
  • 애플리케이션 수준에서 useCase에 직접 연결되는 컴포넌트이므로 입력 포트는 도메인 용어로 SW의 의도를 구현할 수 있게 한다.
  • OutputPort에 의존하며, OutputPort에서 제공하는 소스를 기반으로 useCase를 실제 구현한다.

OutputPort

  • 외부 리소스에서 데이터를 가져와야 하는 상황에서 이 역할을 해준다.
  • useCase나 inputPort가 오퍼레이션을 수행하기 위해서 어떤 종류의 데이터를 외부에서 가져와야 하는지 기술에 구애받지 않고 설명하는 인터페이스로 표현된다.

Framework Hexagon

  • 외부 인터페이스를 제공한다.
  • 입력, 출력 인터페이스를 담당한다.
  • useCase, inputPort, outputPort를 통해서 일부 애플리케이션 특화 오퍼레이션을 다루는 애플리케이션 헥사곤을 외부로 노출시키는 역할을 한다.
  • Driving, Driven 방식이 있다.
  • Driver 관점에서는 inputAdapter를 사용한다. Driven 관점에서는 outputAdapter를 사용한다.

    driven에 대해서?

    • Hexagonal에서 Driven은 헥사고날 애플리케이션 자체에 의해서 오퍼레이션이 유도, 통제되며, 다른 외부 시스템 동작을 트리거하는 경우를 의미한다.

장점

  1. SW 구성하는 기본 원칙 수립에 도움을 준다.
  2. 변경에 용이하며 기술 변화를 흡수할 때 큰 장애물을 만들지 않을 수 있다. (아키텍쳐적으로 유도되므로)
  3. 변경에 강점이 생기면서 유지보수성도 올라간다.
    1. 비즈니스 큐칙 변경은 도메인 헥사곤에 캡슐화되어 있으므로 크게 문제가 되지 않는다.
    2. 새로운 기술, 프로토콜을 위해서는 어댑터만 만들면 된다.
  4. 테스트 용이성이 높다. 외부 의존성 없이도 테스트를 진행할 수 있게 된다.

단점

  1. 코드가 많아진다.
  2. 불필요한 오버헤드가 많아진다.

Hexagonal.png

출처: https://reflectoring.io/spring-hexagonal