일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 테스트주도개발
- GrokkingFunctionalProgramming
- 아키텍처
- 이펙티브코틀린
- 조영호
- 추상화 설계
- template
- web
- 만들면서배우는클린아키텍처
- 계층형아키텍처
- 개발서적
- 함수형프로그래밍
- Kotlin
- 클린아키텍처
- Java
- FP
- 책스터디
- 코틀린
- Spring
- 객체지향의사실과오해
- 스터디
- Thymeleaf
- Boot Legacy 차이점
- DDD
- 개발방법론
- TDD
- 테스트
- 유지보수
- 도메인 주도 개발 시작하기
- 헥사고날아키텍처
- Today
- Total
김동형수 개발기
만들면서 배우는 클린 아키텍처 - 02 정리 본문
02. 의존성 역전하기
객체지향 개발을 잘 하기위한 방법인 'SOLID' 원칙 중 단일 책임 원칙, 의존성 역전 원칙에 대해 다룬다.
단일 책임 원칙
'SOLID' 원칙 중 'S'에 해당하며, 일반적인 해석은 아래와 같다
하나의 컴포넌트는 오로지 한 가지 일만 해야 하고, 그것을 올바르게 수행해야 한다.
그러나 저자의 관점에서는 '책임' = '변경할 이유'라고 해석해서 단일 책임 원칙을 아래와 같이 해석한다.
컴포넌트를 변경하는 이유는 오직 하나뿐이어야 한다.
만약 컴포넌트를 변경할 이유가 한 가지라면 우리가 어떤 다른 이유로 소프트웨어를 변경하더라도 그 이유에 해당하지 않는 컴포넌트에 대해서는 신경쓸 필요가 없다.
변경할 이유라는 것은 컴포넌트 간의 의존성을 통해서 쉽게 전파가 된다.
컴포넌트간 의존성이 존재한다면 의존성을 가진 컴포넌트가 변경될 경우 참조하고 있는 컴포넌트 또한 높은 확률로 함께 변경될 수 있다고 생각한다.
그림 2.1에서 컴포넌트 E가 새로운 기능추가로 변경이 된다면, 참조하고 있는 A,B,D는 높은 확률로 함께 변경이 되어야할 것이다.
단일 책임 원칙을 위반하는 코드는 시간이 지나서 코드의 양이 증가하면서 컴포넌트의 수도 늘어나고 그 의존성이 복잡하게 얼키고 설키면서 변경하는 비용이 증가하게 된다.
부수효과에 관한 이야기
저자의 경험을 기반한 부수효과(side effect)에 대한 내용이며 클라이언트로 하여금 잘못 구조화된 소프트웨어를 변경하는데 비용이 많이 드는 사례를 보여준다.
유지보수 비용을 절감하기 위해 10년동안 개발/유지보수 된 코드를 넘겨받아서 테스트 자동화, 리팩터링 진행
이후 클라이언트의 난해한 기능 추가 요청
사용자 친화적이면서 비용이 적게드는 더 나은 방법 제안, 그러나 이전 개발팀에서 발생했던 부수효과에 대해서 우려해 거절
의존성 역전 원칙
'SOLID' 원칙 중 'D'에 해당한다.
계층형 아키텍처에서 의존성은 다음 계층인 아래 방향을 가리킨다. 웹 -> 도메인, 도메인 -> 영속성
단일 책임 원칙을 적용할 때 상위 계층들이 하위 계층들에 비해 변경할 이유가 더 많다는 것을 알 수 있다.
영속성 계층을 변경하게 되면 거기에 의존성을 가진 도메인 계층을 높은 확률로 변경해야 한다.
영속성 코드가 변경이 되더라도 도메인 코드를 변경하고 싶지 않을 때 의존성 역전 원칙이 답이 된다고 한다.
의존성 역전 원칙의 해석은 아래와 같다.
코드상의 어떤 의존성이든 그 방향을 바꿀 수(역전시킬 수) 있다.
의존성 역전 원칙의 전재조건은 양쪽 코도를 모두 제어할 수 있어야 한다. 만약 서드파티 라이브러리에 대한 의존성이 있다면 제어할 수 없기 때문에 의존성을 역전 시킬 수 없다.
의존성 역전 원칙을 적용하는 간단한 예를 들어보자.
엔티티는 도메인 객체를 표현하고 도메인 코드는 이 엔티티들의 상태를 변경하는 일을 중심으로 하기 때문에 먼저 엔티티를 도메인 계층으로 올린다.
영속성에 있는 리포지토리가 도메인 계층의 엔티티를 참조하기 때문에 순환 의존성이 생긴다.
이 부분이 단일 책임 원칙을 적용하는 부분인데 도메인 계층에 리포지토리 인터페이스를 만들고 구현체는 영속성 계층에서 구현한다.
일반적인 개발 방법론에서 순환 의존성(순환참조)는 피하라고 했던 것 같은데 책에서는 일부러 만들고 있다. 리포지토리 인터페이스와 구현부를 나눔으로서 로 해결이 가능한 내용일까?
위에서 나온 방법으로 문제가 해결되었다고 저자는 말하고 있는데, 정확한 이해가 되지 않아서 다른 스터디 구성원들의 의견을 듣고 다시 이해해야겠다.
클린 아키텍처
로버트 C. 마틴은 클린 아키텍처에서는 설계가 비지니스 규칙의 테스트를 용이하게 하고, 비지니스 규칙은 프레임워크, 데이터베이스, UI 기술, 그 밖의 외부 애플리케이션이나 인터페이스로부터 독립적일 수 있다고 이야기했다.
이는 도메인 코드가 바깥(상위 계층 방향)으로 향하는 어떤 의존성도 없어야 함을 의미한다. 대신 의존성 역전 원칙의 도움으로 모든 의존성이 도메인 코드를 향하고 있다.
이 아키텍처의 코어에는 주변 유스케이스에서 접근하는 엔티티들이 있다.
유스케이스는 단일 책임을 갖기 위해 조금 더 세분화돼 있다. 새분화 된 유스케이스를 통해서 넓은 서비스(메서드가 많고 코드량이 많아 여러 영속성 컴포넌트를 참조하는 서비스 클래스) 문제를 피할 수 있다.
도메인 코드에서는 어떤 영속성 프레임워크가 사용되는지 알 수 없기 때문에 특정 프레임워크에 특화된 코드를 가질 수 없고 비지니스 규칙에 집중할 수 있다.
JPA에 상당히 종속적인 코드의 구성이 대부분인데 적용하려면 상당히 많은 시간을 투자해야 가능할 것 같다.
클린 아키텍처에서도 대가는 있다. 도메인 계층이 영속성이나 외부 계층과 철저하게 분리돼야 하므로 애플리케이션의 엔티티에 대한 모델을 각 계층에서 유지보수해야 한다.
클린 아키텍처도 번거로움이 있다!
영속성 계층에서 ORM 프레임워크를 사용한다고 하면, 도메인 계층은 영속성 계층을 모르기 때문에 도메인 계층에서 사용한 엔티티 클래스를 영속성 계층에서 함께 사용할 수 없다. 그래서 서로 데이터를 주고 받을 때 컨버팅해야하는 수고스러움이 있다. 그러나 이는 바람직한 일이다. 도메인 코드가 프레임워크에 종속되지 않음으로 결합이 제거된 상태이다.
벌써부터 리팩토링할때 험난한 과정이 눈앞을 가린다.
엔티티는 하나로 구성하고 각자 계층에서 상속받는 구조로 사용하면 문제가 될까..? 차후 적용할 때 고민해보도록 하자.
헥사고날 아키텍처
'헥사고날 아키텍처'는 알리스테어 콕번이 만든 용어로, 로버트 C. 마틴이 클린 아키텍처에서 좀 더 일반적인 용어로 설명한 것과 동일한 원칙을 적용한다.
애플리케이션 코어가 육각형으로 표현되어 이 아키텍처의 이름이 됐다. '헥사고날(육각형) 아키텍처' 라고 지어진 이유는 애플리케이션이 다른 시스템이나 어댑터와 연결되는 4개 이상의 면을 가질 수 있음을 보여주기 위해서 사각형 대신 헥사고날(육각형)을 사용했다고 한다.
육각형 안에는 도메인 엔티티, 이와 상호작용하는 유스케이스가 있다. 육각형에서 외부로 향하는 의존성이 없기 떄문에 로버트 C. 마틴이 클린 아키텍처에서 제시한 의존성 규칙이 그대로 적용되었다. 대신 모든 의존성이 코어(도메인 계층 + 애플리케이션 계층)로 향한다.
입력포트를 통해 코어에 의존성이 있다면 애플리케이션을 주도하는 어댑터이고 출력포트를 통해 코어에 의존성이 있다면 애플리케이션이 주도하는 어댑터이다.
이런 아키텍처 스타일은 포트와 어댑터 아키텍처로도 알려져 있다. 가장 바깥쪽에 있는 계층은 애플리케이션과 다른 시스템 간의 번역을 담당하는 어댑터로 구성돼 있다. 다음으로 포트와 우스케이스 구현체를 결합해서 애플리케이션 계층을 구성할 수 있는데, 이 두가지가 애플리케이션의 인터페이스를 정의하기 떄문이다. 마지막 계층에는 도메인 엔티티가 위치한다.
유지보수 가능한 소프트웨어를 만드는 데 어떻게 도움이 될까?
서로 다른 계층간의 의존성을 줄인다면 변경할 이유의 수가 줄일 수 있다. 변경할 이유가 적을수록 유지보수성은 더 좋아진다.
계층형 아키텍처에서 변경하거나 프로젝트 시작부터 헥사고날 아키텍처를 채택해서 하거나 초기 비용(시간, 러닝커브)가 상당할 것 같지만, 변경되는 내용이 많아지는 프로덕트 초반에는 좋은 결과가 될 것 같다.
이후 유지보수할 때도 원칙이 지켜진 아키텍처라면 적은 비용으로 효율적인 유지보수가 진행이 될 수 있을것 같다.
'책 스터디 > [완료] 만들면서 배우는 클린아키텍처' 카테고리의 다른 글
만들면서 배우는 클린 아키텍처 - 06 정리 (0) | 2022.04.13 |
---|---|
만들면서 배우는 클린 아키텍처 - 05 정리 (0) | 2022.04.12 |
만들면서 배우는 클린 아키텍처 - 04 정리 (0) | 2022.04.11 |
만들면서 배우는 클린 아키텍처 - 03 정리 (0) | 2022.04.08 |
만들면서 배우는 클린 아키텍처 - 01 정리 (0) | 2022.04.06 |