왜 클린 아키텍처를 공부하게 되었는가?
나는 모놀리식 아키텍처, 계층형 아키텍처(MVC) 기반의 개인 프로젝트와 짧지만, 레거시 프로젝트를 담당해 개발한 경험이 있다. 그리고 프로젝트를 개발하는데 있어 나는 코드적인 기준(가독성)을 충족하고 빠르고 쉽게(=낮은 개발 비용)으로 개발을 하고싶었다. 하지만 기존의 계층형 아키텍처의 구조상 이는 쉬운 일이 아니었다.
계층형 아키텍처(Layered Architecture)
계층형 아키텍처의 내부 컴포넌트는 수평한 계층(Layer)으로 구성되며, 각 계층은 애플리케이션에서 주어진 역할을 수행하게 된다. 계층형
- 레이어의 종류에는 프리젠테이션(presentation, 웹 계층), 비즈니스(business, 도메인계층), [퍼시스턴스(persistence) , 데이터베이스(database), 영속성 계층]의 4개 표준 레이어 로 구성한다.
- 규모가 작은 애플리케이션은 3개, 덩치가 크고 복잡한 비즈니스 애플리케이션은 5개 또는 그 이상의 레이어로 구성된다.
- 각 레이어는 관심사의 분리(seperation of concerns)의 개념을 통해, 아키텍처 내부의 역할 및 책임 모델을 효과적으로 구성할 수 있다.
- 특정 레이어에 소속된 컴포넌트는 역할 범위가 한정되며 그 레이어에 알맞은 로직만 처리한다.
- 이에 대한 트레이드오프로, 개발자의 기술 역량을 도메인의 (프리젠테이션 로직, 퍼시스턴스로직 등)기술적인 부분에 집중시킬 수 있으나, 전체적인 민첩성(변화에 신속하게 반응하는 능력)이 떨어지게 된다.
계층형 아키텍처의 한계점
아키텍처는 견고한 아키텍처로 전통을 갖고있다. 계층을 잘 이해하고 구성한다면 관심사의 분리로 역활과 책임을 통해 웹 계층이나 영속성 계층에 독립적으로 도메인 로직을 작성할 수 있다. 즉, 기존 기능에 영향을 주지 않고 새로운 기능을 추가할 수 있다. 이렇게 보면 계층형 아키텍처는 아주 좋아보인다. 하지만, 여기에는 잠재적인 위험(한계)가 내재되어있다.
- 모놀리식 아키텍처로, 비즈니스가 복잡해지고, 규모가 커지면 커질수록 점점 더 많은 문제가 발생하고, 이를해결하는데 시간이 점점 더 많이 소요된다.(시간이 지날수록 변경, 개발하기 어려워진다.)
- 팀간 협업을 하는데 있어, 같은 부분을 동시에 작업할 수 없다.(feat. 콘웨이의 법칙)
- 계층의 의존성이 DB(=영속성계층)을 향하게되어 비즈니스(=도메인)이 예상하지 못한 문제로 영향을 받을 수 있다.(=도메인 입장에서 의존성이 비대칭적이다.)
수 많은 위험들 중, 계층의 의존성이 영속성 계층을 향한다는 것에 집중해야한다. 사실 이 부분은 계층형 아키텍처의 토대이자, 당연한 부분이다. 하지만, 이에 대하여 다시 생각해볼 필요가 있다.
우리가 만드는 프로젝트의 목적은 무엇인가? 도메인이자 비즈니스이다. 각 비즈니스 규칙, 비즈니스 모델을 만들고 유지보수하는 것이 목적이다.
그런데 왜 우리는 데이터베이스를 바탕으로 아키텍처를 만들고, 프로젝트를 만들어 나가는것인가?
클린아키텍처(Ports and Adapters)
클린 아키텍처를 떠올린다면, 로버트 C. 마틴의 클린아키텍처 책이 먼저 떠오를 것이다. 이 책에서의 클린 아키텍처는 설계가 비즈니스 규칙의 테스트를 용이하게하고, 비즈니스 규칙은 프레임워크, 데이터베이스, UI 기술, 그 밖의 외부 애플리케이션이나 인터페이스로부터 독립적일 수 있다고 이야기한다. 이는 도메인 코드가 바깥으로 향하는 어떤 의존성도 없어야 가능하다.
지금 이야기하는 클린아키텍처(Ports and Adapters)는 이를 완벽하게 반영했다고 나는 생각한다. 좀 더 이야기를 해본다면, 클린아키텍처는 도메인 중심의 아키텍처로서, 도메인 계층(=비즈니스계층)을 제외한 모든 계층은 분리되어야 하는 외부 요소로 취급한다. 도메인 중심의 아키텍처를 생각해본다면, DDD(Domain Driven Design, 도메인 주도 설계)가 떠오를 것이다. 클린 아키텍처는 도메인 주도 설계를 지원하는 아키텍처이다.
클린아키텍처(Ports and Adapters)에서 애플리케이션은 내부(비즈니스 관심사를 다룸) 와 외부(기술적 관심사를 다룸)으로 나뉘어 지며, 특징은 다음과 같다.
- 가술만 다를 뿐 관심사를 다루지 않는다는 측면에서 보았을 때, 외부요소는 동일하다.
- 의존성의 방향으로 도메인 계층(비즈니스 계층)이 외부 요소에 의존하지 않고, 프리젠테이션계층, 영속성 계층이 도메인 계층에 의존한다.(=도메인 입장에서 의존성이 대칭적이다.)
- 외부에 포함된 기술적인 컴포넌트를 어댑터(Adapter) 라고 부르고, 어댑터가 내부와 상호작용하는 접점을 포트(Port)라고 한다.
이를 통해 얻을 수 있는 효과는 다음과 같다.
- 유연하고 유지보수가 용이한 아키텍처를 갖게 된다.
- 도메인 중심의 개발을 설계할 수 있게 된다.
- 의존성을 강제할 수 있다.
의존성 역전
계층형 아키텍처에서 계층 간 의존성은 항상 다음 계층인 아래 방향을 가리킨다. 영속성 계층에 대한 도메인 계층의 의존성 때문에 영속성 계층을 변경할 때마다 잠재적으로 도메인 계층도 변경해야한다. 하지만 클린 아키텍처에서는 영속성 코드가 바뀐다고 해서 도메인 코드까지 바꾸고 싶지 않다. 그리고이 문제를 헤결하기 위해 의존성 역전 원칙을 적용한다.
클린아키텍처에서는 port 인터페이스를 사용하여 도메인의 영속성 계층에 대한 의존성을 도메인 계층으로 의존성을 역전시켰다. 이를 통해 영속성 코드에 있는 잠재적 위험요소로 부터 도메인을 보호한다.
- 엔티티는 도메인 객체를 표현하고 도메인 코드는 이 엔티티들의 상태를 변경하는 일을 중심으로 하기 때문에 엔티티를 도메인 계층으로 올려야한다.
- 이와 관련하여, 도메인 계층의 엔터티를 영속성 엔터티를 함께 작성해야하는 수고가 발생한다.(영속성 계층 이외의 모든 계층에서 도메인 엔터티에 대한 모델을 각각 작성해야한다. 트레이드오프)
- 도메인 계층과 영속성 계층이 데이터를 주고 받을 때, 두 엔터티를 변환(Mapper) 가 필요하다.(도메인과 다른 계층 간 통신도 동일하다.)
이 아키텍처에서 가장 중요한 것은 의존성 규칙이다. 계층 간의 모든 의존성은 반드시 안쪽으로 향해야한다.
육각형 아키텍처는 애플리케이션 코어가 각 어댑터와 상호 작용하기 위해 특정 포트를 제공하기 때문에 Ports and Adapters 아키텍처라고 불린다. 여기서 육각형 모양은 아무 의미가 없다. 그저 애플리케이션이 다른 시스템 혹은 외부 어댑터와 4개 이상 연결될 수 있음을 표현하기 위해 사각형이 아닌 육각형을 선택했다고 한다.
- Entity(붉은색)는 Domain-Core 계층에 해당한다.
- UseCase(파란색)는 Application 계층에 해당한다.
- 왼쪽에 있는 어댑터(input) 는 애플리케이션 코어를 호출하며, 애플리케이션을 주도한다.
- 오른쪽에 있는 어댑터(output) 은 애플리케이션 코어에의해 호출되며, 애플리케이션에 의해 주도된다.
- 각 Port 는 Application(도메인 계층) 와 통신하기 위해 존재한다.
정리
(나는) 왜 클린 아키텍처를 공부하게 되었는가?
- 나는 유연하고 유지보수가 용이하며, 확장성이 뛰어난 아키텍처를 갖고 싶었다.
- 기능 개발과 협업 간 동시 작업이 가능한 아키텍처를 만들고 싶었다.
- 기술 중심의 개발이 아닌 비즈니스(도메인)중심의 개발을 할 수 있는 개발자가 되고 싶었다.
이런 목표를 가진 내게 클린 아키텍처(Ports and Adapters) 는 너무 매력적인 주제로 다가왔고, 공부하게 되었다.
클린 아키텍처(Ports and Adapters) 는 계층형 아키텍처의 가장 큰 문제점(의존성 규칙)을 의존성 역전을 통해 극복하고, 모든 계층의 의존성의 방향은 도메인 계층을 향하게 하였다.
- 외부 요인과 관련된 모든 문제로부터 도메인 로직의 결합을 제거하고, 도메인 로직의 변경의 이유를 줄였다.
- 도메인 코드는 비즈니스 문제에 알맞도록 자유롭게 모델링 될 수 있으며, 영속성 코드와 같은 외부 요소들은 각 계층의 속성에 맞게 자유롭게 모델링이 가능하다.
- Adapter, Application, Domain 으로 구성된다.
참고 자료
만들면서 배우는 클린 아키텍처 - YES24
우리 모두는 낮은 개발 비용으로 유연하고 적응이 쉬운 소프트웨어 아키텍처를 구축하고자 한다. 그러나 불합리한 기한과 쉬워보이는 지름길은 이러한 아키텍처를 구축하는 것을 매우 어렵게
www.yes24.com
GitHub - KEEMSY/shoes-ordering-system: shoes-ordering-system
shoes-ordering-system. Contribute to KEEMSY/shoes-ordering-system development by creating an account on GitHub.
github.com
'개인공부 > 아키텍처' 카테고리의 다른 글
[ 아키텍처 ] 로드밸런싱 패턴 (1) | 2023.10.29 |
---|---|
[ 개인 공부 ] 코드의 디커플링에 관하여 (1) | 2023.10.24 |
[ 아키텍처 ] 클린아키텍처에서의 유스케이스 구현하기 (0) | 2023.08.02 |
[ 아키텍처 ] 클린아키텍처의 구성과 패키지 구조 (0) | 2023.07.24 |
[아키텍처] 클린아키텍처(Ports and Adapters) (0) | 2023.07.20 |