객체지향 SOLID 원칙은 가장 기본적이면서 광범위하게 사용되고 있는 설계 규칙이다. (다양한 책에서 빠지지 않고 언급되는 원칙이다.)
이번 장에서는 단일 책임 원칙(Single Responsibility Principle, SRP)과 의존성 역전 원칙(Dependency Inversion Principle, DIP)을 다룬다.
단일 책임 원칙
일반적으로 단일 책임 원칙의 해석은 아래와 같다.
하나의 컴포넌트는 오로지 한 가지 일만 해야하고, 그것을 올바르게 수행해야 한다.
직관적으로 해석하다 보니 오해의 여지가 생겨 잘못 이해하는 경우가 있다.
실제 정의는 다음과 같다
컴포넌트를 변경하는 이유는 오직 하나뿐이어야 한다.
'책임'을 한 가지 일만 하는 것이 아니라 '변경할 이유'로 해석하는 것이 올바르다.
단일 책임 원칙보다는 단일 변경 이유 원칙으로 이해하는 게 더 알맞다.
아키텍처에서의 의미 (부수효과 발생)
컴포넌트를 변경할 이유가 한 가지라면 우리가 어떤 다른 이유로 소프트웨어를 변경해도 이 컴포넌트를 신경 쓸 필요가 없다. 변경돼도 기대한 대로 동작하기 때문이다.
하지만 변경할 이유라는 것은 컴포넌트 간의 의존성을 통해 쉽게 전파된다.
그림을 보면 컴포넌트의 의존성 각각은 이 컴포넌트를 변경하는 이유 하나씩에 해당된다.
A 컴포넌트는 다른 여러 컴포넌트를 의존(직접적이든 의존적이든)하게 된다. 반면에 E는 의존하는 컴포넌트가 없다.
E 컴포넌트가 변경되는 이유는 새로운 요구사항으로 E의 기능을 바꿀 때 밖에 없다.
하지만 A 컴포넌트는 모든 컴포넌트에 의존되고 있기 때문에 영향을 받아 같이 변경되어야 한다.
계층형 아키텍처를 생각해보면 계층 간 의존성은 항상 아래 방향을 가리킨다. 위의 그림처럼 상위 계층은 아래의 계층의 영향을 받아 변경할 이유가 많아진다.
어떻게 해야 이런 의존성을 끊을 수 있을까? 해답은 의존성 역전 원칙이다.
의존성 역전 원칙
의존성 역전 원칙은 이름 그대로를 의미한다.
코드 상의 어떤 의존성이든 그 방향을 바꿀 수(역전시킬 수) 있다.
동작 원리
1장에서 봤던 구조를 다시 되새겨보자, 도메인 계층의 서비스가 영속성 계층의 엔티티와 리포지토리를 의존한다.
이 구조의 의존성을 역전시켜보자.
- 엔티티는 도메인 객체를 표현하고 도메인 코드는 엔티티의 상태를 변경하기 때문에 도메인 계층으로 올린다.
- 영속성 계층의 리포지토리가 도메인 계층의 엔티티를 의존하고 있기에 순환 의존성(Circular Dependency)이 생겼는데, 여기에 의존성 역전 원칙을 적용한다.
- 도메인 계층에 리포지토리 인터페이스를 만들고, 실제 리포지토리는 영속성 계층에서 구현한다.
이 덕분에 도메인 로직이 영속성 계층의 의존성에서 해방되었다.
클린 아키텍처
클린 아키텍처에서는 설계가 비즈니스 규칙의 테스트를 용이하게 하고, 비즈니스 규칙은 프레임워크, 데이터베이스, UI 기술, 그 밖의 외부 애플리케이션이나 인터페이스로부터 독립적이다 - 클린 아키텍처, 로버트 C 마틴
로버트 C 마틴의 주장에 따르면 도메인 코드가 바깥으로 향하는 어떤 의존성이 없어야 함을 의미한다.
대신 모든 의존성이 도메인 코드를 향하고 있다.
가장 중심에 도메인 코드가 존재하기 때문에, 도메인 코드는 어떤 영속성 프레임워크나 UI 프레임워크가 사용되는지 알 수 없다. 이 덕분에 특정 프레임워크에 종속되지 않고 비즈니스 규칙에 집중할 수 있다.
클린 아키텍처의 대가가 따른다
도메인 계층이 영속성이나 UI 같은 외부 계층에 분리되기 때문에, 애플리케이션의 엔티티에 대한 모델을 각 계층에서 유지 보수해야 한다.
ORM 프레임워크를 사용하면 도메인 계층과 영속성 계층이 데이터를 주고받을 때, 두 엔티티를 서로 변환해야 한다.
육각형 아키텍처(헥사고날 아키텍처)
육각형 아키텍처는 알라스테어 콕번이 만든 용어로 클린 아키텍처의 추상적인 원칙을 좀 더 구체적인 원칙으로 보여준다.
이 아키텍처에서 육각형 모양은 아무 의미도 없다. 다른 시스템이나 어댑터와 연결되는 4개 이상의 면을 가질 수 있다는 것을 보여주기 위해 육각형을 사용했다고 한다.
육각형 아키텍처를 보면 클린 아키텍처와 동일하게 모든 의존성이 도메인 로직을 향한다.
육각형 밖에는 애플리케이션과 상호작용하는 다양한 어댑터가 있는데, 왼쪽 어댑터는 애플리케이션을 주도하는 어댑터(driving adapter)이고 오른쪽 어댑터는 애플리케이션에 의해 주도되는 어댑터(driven adapter)다.
육각형 아키텍처는 애플리케이션 코어가 각 어댑터와 상호작용하기 위해 특정 포트를 제공한다. 이 때문에 '포트와 어댑터(ports-and-adapters)' 아키텍처라고 부르기도 한다.
유지보수 가능한 소프트웨어를 만드는 데 어떻게 도움이 될까?
클린 아키텍처, 육각형 아키텍처 같이 의존성을 역전시켜 도메인 코드가 외부에 의존하지 않게 하는 것은 결합을 줄이고 변경의 이유를 줄이고 유지보수성을 좋게 한다.
또한 도메인 코드는 비즈니스 문제에 자유롭게 모델링 되고, 영속성 계층과 UI 계층도 각 문제에 맞게 모델링이 될 수 있다.
주관적인 생각을 더해 책의 내용을 정리하니 자세한 내용이 궁금하면 만들면서 배우는 클린 아키텍처를 참고해주세요.
'서적 > 만들면서 배우는 클린 아키텍처' 카테고리의 다른 글
1장 - 계층형 아키텍처의 문제는 무엇일까? (0) | 2021.12.16 |
---|---|
시작글 - 만들면서 배우는 클린 아키텍처 (0) | 2021.12.15 |