Ch30. 데이터베이스는 세부사항이다.
아키텍처 관점에서 볼 때 데이터베이스는 엔티티가 아니다.
즉, 데이터베이스는 세부사항이라서 아키텍처의 구성요소 수준으로 끌어올릴 수 없다.
데이터베이스는 일개 소프트웨어이며, 데이터에 접근할 방법을 제공하는 유틸리티다.
이러한 유틸리티는 저수준의 세부사항(메커니즘)일 뿐이라서 아키텍처와는 관련이 없다.
[관계형 데이터베이스]
관계형 데이터베이스는 세부사항이다.
관계형 테이블은 특정한 형식의 데이터가 접근하는 경우에는 편리하지만, 데이터를 테이블에 행 단위로 배치한다는 자체는 아키텍처적으로 볼 때 전혀 중요하지 않다.
애플리케이션의 유스케이스는 이러한 방식을 알아서는 안되며 관여해서도 안 된다.
많은 데이터 접근 프레임워크가 테이블과 행이 객체 형태로 시스템 여기저기에서 돌아다니게 허용하는데,
아키텍처적으로 잘못된 설계다.
이렇게 하면 유스케이스, 업무 규칙, 심지어는 UI조차도 관계형 데이터 구조에 결합되어 버린다.
[데이터베이스 시스템은 왜 이렇게 널리 사용되는가?]
예전에는 디스크를 사용했는데, 디스크는 몇 밀리초의 작업 속도가 걸렸고,
이런 피해갈 수 없는 시간 지연을 완화하기 위해 색인, 캐시, 쿼리 계획 최적화가 필요해졌다.
이러한 색인, 캐시, 쿼리 계획 작업은 데이터 대상이 누구인지 알 수 있어야 했다.
이러한 데이터 관리 시스템이 시간이 지나면서 두 가지로 유형으로 분리되었는데,
하나는 파일 시스템이고, 다른 하나는 관계형 데이터베이스 관리 시스템(RDBMS)이었다.
파일 시스템은 문서(document) 기반이다.
파일 시스템은 문서 전체를 자연스럽고 편리하게 저장하는 방법을 제공한다.
데이터베이스 시스템은 내용 기반이다.
데이터베이스 시스템은 내용을 기반으로 레코드를 자연스럽고 편리하게 찾는 방법을 제공한다.
[세부사항]
데이터베이스가 세부사항이라고 말하는 이유는 데이터가 데이터베이스에 있더라도,
RAM으로 읽은 후 다루기 편리한 형태로 그 구조를 변경한다.
즉, 데이터베이스는 그저 메커니즘에 불과하며, 디스크 표면과 RAM 사이에서 데이터를 이리저리 옮길 때 사용할 뿐이다.
[하지만 성능은?]
데이터 저장소의 측면에서 성능은 완전히 캡슐화하여 업무 규칙과는 분리할 수 있는 관심사다.
데이터 저장소에서 데이터를 빠르게 넣고 뺄 수 있어야 하는 것은 맞지만, 이는 저수준의 관심사다.
성능은 시스템의 전반적인 아키텍처와는 아무런 관련이 없다.
[결론]
체계화된 데이터 구조와 데이터 모델은 아키텍처적으로 중요하다.
하지만 그저 데이터를 회전식 자기 디스크 표면에서 이리저리 옮길 뿐인 기술과 시스템은 아키텍처적으로 중요하지 않다. 데이터베이스가 이에 속한다.
데이터는 중요하다. 데이터베이스는 세부사항이다.
Ch31. 웹은 세부사항이다.
[끝없이 반복하는 추]
우리는 연산 능력을 어디에 둘지 알 수 없다.
연산 능력을 중앙에 집중하는 방식과 분산하는 방식 사이에서 우리는 끊임없이 움직인다.
그리고 내 생각에 이러한 진동은 한동안 계속될 것이다.
웹도 그 진동 중 하나에 불과하다.
[요약]
GUI는 세부사항이다. 웹은 GUI다. 따라서 웹은 세부사항이다.
그리고 아키텍트라면 이러한 세부사항을 핵심 업무 로직에서 분리된 경계 바깥에 두어야 한다.
웹은 입출력 장치다.
웹과 같은 GUI는 너무 특이하고 다채롭기 때문에 장치 독립적인 아키텍처를 추구하는 일이 터무니없다고 말할 수 있다.
하지만 UI와 애플리케이션 사이에는 추상화가 가능한 또 다른 경계가 존재한다.
업무 로직은 다수의 유스케이스로 구성되며, 각 유스케이스는 사용자를 대신해 일부 함수를 수행하는 것을 볼 수 있다.
UI와 애플리케이션이 춤추는 동안, 어떤 시점이 되면 입력 데이터가 완전히 구성될 것이고, 그러면 유스케이스를 실행할 수 있게 된다.
결국 입력 데이터와 그에 따른 출력 데이터는 유스케이스를 통해 전달되어 처리되고, 이 방식을 따르면 각 유스케이스가 장치 독립적인 방식으로 UI라는 입출력 장치를 동작시킨다고 간주할 수 있다.
[결론]
이러한 종류의 추상화는 만들기 쉽지 않고, 제대로 만들려면 수차례의 반복 과정을 거쳐야 할 것이다.
Ch32. 프레임워크는 세부사항이다.
프레임워크가 아무리 인기가 많아도, 아키텍처가 될 수 없다.
[프레임워크 제작자]
대다수의 프레임워크 제작자는 커뮤니티에 도움이 되기를 바라는 마음에 자신의 작업물을 무료로 제공한다.
이들은 받은 것을 되돌려 주고 싶어 한다.
하지만 이것은 당신이 풀어야할 관심사를 염두에 두지 않는다.
물론 당신의 문제와 프레음워크가 풀려는 문제는 꽤 많이 겹칠 것이다.
겹치지 않았다면 프레임워크가 그렇게 큰 인기를 끌지 못했을 것이다.
[혼인 관계의 비대칭성]
당신과 프레임워크 제작자 사이의 관계는 놀라울 정도로 비대칭적이다.
당신은 대단히 헌신해야 하지만, 프레임워크 제작자는 당신을 위해 아무런 헌신을 하지 않는다.
그리고 제작자들은 당신도 프레임워크에 결합되기를 원한다.
한번 결합하면 그 관계를 깨기가 매우 어렵다.
사실상 프레임워크 제작자는 당신에게 프레임워크와 혼인하기를 요구하는 것이다.
[위험 요인]
프레임워크를 쓴다면 다음과 같은 위험 요인들이 발생할 수 있다.
- 프레임워크의 아키텍처는 그다지 깔끔하지 않은 경우가 많다. 프레임워크는 의존성 규칙을 위반하는 경향이 있다. 업무 객체를 만들 때, 프레임워크 제작자는 자신의 코드를 상속할 것을 요구한다. 프레임워크는 당신의 가장 안쪽 원과 결합되기를 원하는데, 한번 안으로 들어가면 다시는 원 밖으로 못 나올것이다.
- 프레임워크는 애플리케이션의 초기 기능을 만드는 데 도움이 될 것이다. 하지만 제품이 성숙해지면서 프레임워크가 제공하는 기능과 틀을 벗어나게 될 것이다.
- 프레임워크는 당신에게 도움되지 않는 방향으로 진화할 수도 있다.
- 새롭고 더 나은 프레임워크가 등장해서 갈아타고 싶을 수도 있다.
[해결책]
해결책은 무엇인가?
프레임워크와 결혼하지 말라!
그래, 프레임워크를 사용할 수 있다. 다만, 프레임워크와 결합해서는 안 된다.
적당한 거리를 두자. 프레임워크가 아키텍처의 안쪽 원으로 들어오지 못하게 하라.
업무 객체를 만들 때 프레임워크가 자신의 기반 클래스로부터 파생하기를 요구한다면 거절하라!
대신 프록시를만들고, 업무 규칙에 플러그인할 수 있는 컴포넌트에 이들 프록시를 두어라.
프레임워크가 핵심 코드 안으로 들어오지 못하게 하라.
[이제 선언합니다]
정말로 결혼해야만 하는 프레임워크도 있다.
C++을 사용하면 STL과 결혼을, 자바를 사용하면 표준 라이브러리와 반드시 결혼을 해야 한다.
이러한 관계는 정상이지만 선택적이어야 한다.
[결론]
프레임워크와의 첫만남부터 바로 결혼하려고 들지 말라.
가급적이면 프레임워크를 가능한 한 오랫동안 아키텍처 경계 너머에 두자.
Ch33. 사례 연구: 비디오 판매
[제품]
이번 사례 연구는 비디오를 판매하는 소프트웨어다.
이 소프트웨어의 기본적인 발상은 단순하다. 판매하길 원하는 비디오들이 있고, 그걸 개인과 기업에게 웹을 통해 판매한다.
일반적으로 개인은 시청자인 동시에 구매자이며, 기업은 다른 사람들이 시청할 비디오를 구매하는 사람이 따로 있다.
비디오 제작자는 비디오 파일과 비디오에 대한 설명서, 부속 파일을 제공해야 한다.
관리자는 신규 비디오 시리즈물을 추가하거나 기존 시리즈물에 비디오를 추가 또는 삭제하며, 다양한 라이선스에 맞춰 가격을 책정한다.
시스템의 초기 아키텍처를 결정하는 첫 단계는 액터와 유스케이스를 구별하는 일이다.
[유스케이스 분석]
그림 33.1은 전형적인 유스케이스 분석을 보여준다.
네 개의 주요 액터는 분명하다. 단일 책임 원칙에 따르면 이들 네 액터가 시스템이 변경되어야 할 네 가지 주요 원인이 된다.

신규 기능을 추가하거나 기존 기능을 변경해야 한다면, 그 이유는 반드시 이들 엑터 중 하나에게 해당 기능을 제공하기 위해서다.
[컴포넌트 아키텍처]
이제 액터와 유스케이스를 식별했으므로, 예비 단계의 컴포넌트 아키텍처를 만들어 볼 수 있다.

늘 그렇듯이 그림에서 이중선은 아키텍처 경계를 나타낸다.
뷰, 프레젠터, 인터랙터, 컨트롤러로 분리된 전형적인 분할 방법을 확인할 수 있다.
정말로 시스템을 이러한 컴포넌트들로 모두 분할해서 여러 개의 .jar나 .dll 파일로 전달해야 할까?
그럴 수도 있고 아닐 수도 있다.
나는(저자) 컴파일과 빌드 환경을 분명히 이 형태로 나눌 것이며, 따라서 각 컴포넌트를 독립적으로 전달할 수 있게 빌드하는 것도 가능할 것이다.
또한 전달해야 할 이 모든 단위를 더 적은 개수로 합칠 수도 있다.
예를 들어 그림 33.2 같이 분할했다면 총 다섯 개의 .jar 파일로 쉽게 합칠 수 있을 것이다.
즉 뷰, 프레젠터, 인터렉터, 컨트롤러, 유틸리티 각각의 하나의 .jar 파일로 만들 수 있다.
그러면 서로 독립적으로 변경될 가능성이 큰 컴포넌트들을 독립적으로 배포가 가능하다.
이처럼 선택지를 열어두면, 후에 시스템이 변경되는 양상에 맞춰 시스템 배포 방식을 조정할 수 있다.
[의존성 관리]
그림 33.2에서 제어흐름은 오른쪽에서 왼쪽으로 이동한다.
모든 화살표가 오른쪽에서 왼쪽으로 가리키지는 않음을 주목하자.
사실 대다수의 화살표는 왼쪽에서 오른쪽으로 이동한다.
이는 아키텍처가 의존성 규칙을 준수하기 때문이다.
모든 의존성은 경계선을 한 방향으로만 가로지르는데, 항상 더 높은 수준의 정책을 포함하는 컴포넌트로 향한다.
[결론]
그림 33.2의 아키텍처 다이어그램은 두 가지 서로 다른 차원의 분리 개념을 포함하고 있다.
하나는 단일 책임 원칙에 기반한 액터의 분리며, 두번째는 의존성 규칙이다.
이 두 차원은 모두 서로 다른 이유로, 서로 다른 속도로 변경되는 컴포넌트로 분리되는데 그 목적이 있다.
Ch34. 빠져 있는 장
(참고: 사이몬 브라운(Simon Brown 기고)
지금까지 읽은 모든 조언은 더 나은 소프트웨어를 설계하는 데 확실히 도움이 될 것이다.
이러한 소프트웨어는 올바르게 정의된 경계, 명확한 책임, 그리고 통제된 의존성을 가진 클래스와 컴포넌트로 구성될 것이다.
다음 예시를 한번 이제 구현해보자.
온라임 서점을 구축하고 있으며, 고객이 주문 상태를 조회할 수 있어야 한다는 유스케이스를 구현해보자.
[계층 기반 패키지]
아마도 가장 단순한 첫번째 설계 방식은 전통적인 수평 계층형 아키텍처다.
기술적인 관점에서 해당 코드가 하는 일에 기반해 그 코드를 분할한다.
흔히 우리는 이 방식을 ‘계층 기반 패키지’라고 부른다.
그림 34.1의 UML 클래스 다이어그램에서 계층 기반 패키지가 어떤지 볼 수 있다.
이 전형적인 계층형 아키텍처는 계층이라는 얇은 수평 조각으로 나뉘며, 각 계층은 유사한 종류의 것들을 묶는 도구로 사용된다.
‘엄격한 계층형 아키텍처’의 경우, 반드시 아래 계층에만 의존해야 한다.

- OrdersController: 웹 컨트롤러이며, 웹 기반 요청을 처리한다. Spring MVC 컨트롤러가 이에 해당한다.
- OrdersService: 주문 관련 ‘업무 규칙’을 정의하는 인터페이스
- OrderServiceImpl: OrderService의 구현체
- OrdersRepository: 영구 저장된 주문 정보에 접근하는 방법을 정의하는 인터페이스
- JdbcOrdersRepository: OrdersRepository 인터페이스의 구현체
마틴 파울러는 처음 시작하기에는 계층형 아키텍처가 적합하다고 얘기했다.
이게 마틴만의 얘기는 아니다.
다수의 책, 튜토리얼, 교육 과정, 샘플 코드 또한 계층형 아키텍처를 만드는 길로 인도한다.
문제는 마틴이 지적했듯이, 소프트웨어가 커지고 복잡해지기 시작하면, 머지 않아 큰 그릇 세개만으로는 모든 코드를 담기에 부족하다는 사실을 깨닫고, 더 잘게 모듈화해야 할지를 고민하게 될 것이다.
엉클 밥이 이미 언급했듯이, 계층형 아키텍처는 업무 도메인에 대해 아무것도 말해주지 않는다는 문제도 있다.
전혀 다른 업무 도메인이라도 코드를 계층형 아키텍처로 만들어서 나란히 놓고 보면, 웹, 서비스, 리포지터리로 구성된 모습이 기분 나쁠 정도로 비슷하게 보일 것이다.
[기능 기반 패키지]
코드를 조직화하는 또 다른 선택지로 ‘기능 기반 패키지’ 구조도 있다.
이는 서로 연관된 기능, 도메인 개념, 또는 (도메인 주도 설계 용어를 사용한다면) Aggregate Root에 기반하여 수직의 얇은 조각으로 코드를 나누는 형식이다.
그림 34.2에서 보듯이 등장하는 인터페이스와 클래스는 이전과 같지만, 모두가 (세 개가 아닌) 단 하나의 패키지에 속한다.
이는 ‘계층 기반 패키지’를 아주 간단한 리팩터링한 형태지만, 이제 코드의 상위 수준구조가 업무 도메인에 대해 무언가를 알려주게 된다.

드디어 우리는 이 코드 베이스가 웹, 서비스, 리포지터리가 아니라 주문과 관련된 무언가를 한다는 걸 볼 수 있다.
또 다른 이점은 ‘주문 조회하기’ 유스케이스가 변경될 경우 변경해야 할 코드를 모두 찾는 작업이 더 쉬워질 것이다.
변경해야 할 코드가 여러 군데 퍼져 있지 않고 한 패키지에 담겨 있기 때문이다.
나는 소프트웨어 개발팀이 수평적 계층화(계층 기반 패키지)의 문제를 깨닫고, 수직적 계층화(기능 기반 패키지)로 전환하는 걸 자주 목격했다.
내가 보기엔 둘 다 차선책이다.
[포트와 어댑터]
엉클 밥에 따르면, ‘포트와 어댑터(Ports and Adapters)’ 혹은 ‘육각형 아키텍처(Hexagonal Architecture)’, ‘경계, 컨트롤러, 엔티티(BCE)’등의 방식으로 접근하는 이유는 업무/도메인에 초점을 둔 코드가 프레임워크나 데이터베이스 같은 기술적은 세부 구현과 독립적이며 분리된 아키텍처를 만들기 위해서다.
요약하면 그림 34.3에서 제시한 것처럼, 코드 베이스는 ‘내부(도메인)’와 ‘외부(인프라)’로 구성됨을 흔히 볼 수 있다.

‘내부’ 영역은 도메인 개념을 모두 포함하는 반면, ‘외부’ 영역은 외부 세계(예를 들면 UI, 데이터베이스, 서드파티 통합)와의 상호작용을 포함한다.
여기서 주요 규칙은 바로 ‘외부’가 ‘내부’에 의존하며, 절대 그 반대로는 안 된다는 점이다.
그림 34.4는 ‘주문 조회하기’ 유스케이스를 이 방식으로 구현한 모습이다.

여기에서 com.mycompany.myapp.domain 패키지가 ‘내부’이며, 나머지 패키지는 모두 ‘외부’다.
외존성이 ‘내부’를 향해 흐르는 모습에 주의하라.
예리한 독자라면 이전 다이어그램의 OrderRepository가 Orders라는 간단한 이름으로 바뀌었음을 눈치챘을 것이다.
이는 도메인 주도 설계라는 세계관에서 비롯된 명명법으로, 도메인 주도 설계에서는 ‘내부’에 존재하는 모든 것의 이름은 반드시 ‘유비쿼터스 도메인 언어’ 관점에서 기술하라고 조언한다.
바꿔 말하면, 도메인에 대해 논의할 때 우리는 ‘주문’에 대해 말하는 것이지, ‘주문 리포지터리’에 대해 말하는 것이 아니다.
[컴포넌트 기반 패키지]
SOLID, REP, CCP, CRP 그리고 이 책에 나온 대다수의 조언에 대해서 나는 전적으로 공감하지만, 코드를 조직화하는 방법에 대해서는 다소 다른 결론에 이르렀다.
그래서 또 다른 선택지를 제시하려고 하는데, 나는 이 방법을 ‘컴포넌트 기반 패키지’라고 부른다.
지금까지 나는 대다수를 전통적인 계층형 아키텍처를 기반으로 작업을 진행하였다.
계층형 아키텍처를 좋지 않은 아키텍처로 여겨야 하는 이유를 몇 가지 들었지만, 이게 전부는 아니다.
계층형 아키텍처의 목적은 기능이 같은 코드끼리 분리하는 것이다.
엄격한 계층형 아키텍처의 경우에는 반드시 각 계층은 아래 계층에만 의존해야 한다.
이런 방식은 멋지고 깔끔한 비순환 의존성 그래프를 만들 수 있을 것이라 생각하지만, 정말로 코드 베이스의 요소들이 서로 의존할 때는 몇 가지 규칙을 반드시 지켜야 한다.
예를 들어 신규 입사자가 와서 빠르게 기능을 개발하고 싶다고 가정해보자.
OrdersController에서 OrdersRepository를 의존해도 내가 원하는 기능을 구현할 수 있을 것이다.
이러한 아키텍처를 완화된 계층형 아키텍처라고 부른다.
이는 의도된 경우도 있는데, CQRS 패턴이 그 예다. 이외는 대부분 우회하는 일은 바람직하지 못하다.

여기에서 우리에게 필요한 것은 지침(아키텍처 원칙)으로, “웹 컨트롤러는 절대로 리포지터리를 직접 접근해서는 안 된다.”와 같은 원칙이 필요하다.
문제는 강제성이다. 몇몇 팀은 빌드 시 정적 분석 도구(예, NDepend, Structure 101, Checkstyle)를 사용해서 아키텍처적인 위반 사항이 없는지 검사하여 자동으로 강제한다고 한다.
개인적으로 가능하면 컴파일러를 사용해서 아키텍처를 강제하는 방법을 선호한다.
‘컴포넌트 기반 패키지’를 도입해야 하는 이유는 바로 이 때문이다.
이 접근법은 지금까지 우리가 본 모든 것들을 혼합한 것으로, 큰 단위의 단일 컴포넌트와 관련된 모든 책임을 하나의 자바 패키지로 묶는 데 주안점을 둔다.
이 접근법은 서비스 중심적인 시각으로 소프트웨어 시스템을 바라보며, 마이크로 서비스 아키텍처가 가진 시각과 동일하다.
포트와 어댑터에서 웹을 그저 또 다른 전달 메커니즘으로 취급하는 것과 마찬가지로, 컴포넌트 기반 패키지에서도 사용자 인터페이스를 큰 단위의 컴포넌트로부터 분리해서 유지한다.
그림 34.6에서 한번 살펴보자.

본직적으로 이 접근법은 ‘업무 로직과’ 영속성 관련 코드를 하나로 묶는데, 이 묶음을 ‘컴포넌트’라고 한다.
엉클 밥은 이 책 앞부분에서 ‘컴포넌트’를 아래와 같이 정의했다.
컴포넌트는 배포 단위다. 컴포넌트는 시스템의 구성 요소로, 배포할 수 있는 가장 작은 단위다. 자바의 경우 jar 파일이 컴포넌트다.
컴포넌트에 대한 내 정의는 약간 다르다.
“컴포넌트는 멋지고 깔끔한 인터페이스로 감싸진 연관된 기능들의 묶음으로, 애플리케이션과 같은 실행 환경 내부에 존재한다.”
이 정의는 나의 ‘C4 소프트웨어 아키텍처 모델’에 따른 것으로, 소프트웨어 시스템의 정적 구조를 컨테이너, 컴포넌트, 클래스(또는 코드)의 측면에서 계층적으로 생각하는 간단한 방법이다.
컴포넌트 기반 패키지 접근법의 주된 이점은 주문과 관련된 무언가를 코딩할 때, 오직 한 곳 OrdersComponent만 둘러보면 된다는 점이다.
[조직화 vs 캡슐화]
만약 자바 애플리케이션에서 모든 타입을 public으로 지정한다면, 패키지는 단순히 조직화를 위한 메커니즘(폴더와 같이 무언가를 묶는 방식)으로 전락하여 캡슐화를 위한 메커니즘이 될 수 없다.
public 지시자를 과용하면 이 장의 앞에서 제시한 네 가지 아키텍처 접근법은 본질적으로 완전히 같아진다.(그림 34.7)

만약 다이어그램에서 패키지 구조를 살려 더 제한적인 접근 지시자를 사용할 수 있는 타입을 (흐리게)표시하면, 다이어그램은 상당히 인상적으로 변한다.(그림 34.8)

분명하게 해 두고 싶은 점은, 여기에서 설명한 내용은 모노리틱 애플리케이션에 대한 것으로, 모든 코드가 단 하나의 소스 코드 트리에 존재하는 경우다.
[다른 결합 분리 모드]
프로그래밍 언어가 제공하는 방법 외에도 소스 코드 의존성을 분리하는 방법은 존재할 수 있다.
자바 9에서 제공하는 모듈 시스템을 도입하는 경우, public 타입과 외부에 공표할 타입을 분리할 수 있다.
자바 9의 모듈 시스템은 더 나은 소프트웨어를 빌드할 수 있는 새로운 도구를 제공할 것이며, 다시 한번 설계에 대한 고민하도록 관심을 불러 일으키는 것이기에 열렬한 지지를 보낸다.
다른 분리 방법은 소스 코드 수준에서 의존성을 분리하는 방법도 있다.
정확하게는 서로 다른 소스 코드 트리로 분리하는 방법이다.
포트와 어댑터를 예로 들자면, 다음과 같은 소스 코드 트리를 만들 수 있다.
- 업무용 도메인용 소스 코드(즉, 선택된 기술이나 프레임워크와는 독립적인 모든 것): OrdersService, OrdersServiceImpl, Orders)
- 웹용 소스 코드: OrdersController
- 데이터 영속성용 소스 코드: JdbcOrdersRepository
구현 관점에서 이렇게 분리하면 빌드 도구(예를 들어 Maven, Gradle, MSBuild)를 사용해서 모듈이나 프로젝트가 서로 분리되도록 구성해야 한다.
포트와 어댑터 접근법을 적용할 때는 이보다 간단한 방법을 사용하기도 한다.
단순히 소스 코드 트리를 두 개만 만드는 것이다.
- 도메인 코드(’내부’)
- 인프라 코드(’외부’)
이 방식은 그림 34.9와 같은 멋진 다이어그램으로 표현되며, 많은 사람이 포트와 어댑터 아키텍처를 간략하게 설명할 때 쓰는 그림이다.
이 다이어그램에서 인프라는 도메인에 대한 컴포일 시점의 의존성을 가진다.

[결론: 빠져 있는 조언]
이 장은 최적의 설계를 꾀했더라도, 구현 전략에 얽힌 복잡함을 고려하지 않으면 설계가 순식간에 망가질 수도 있다는 사실을 강조하는데 그 목적이 있다.
가능하면 선택사항을 열어두되, 실용주의적으로 행해라.
'Book Notes' 카테고리의 다른 글
| [개발서적] Clean Architecture 5부(ch25~28) 요약 (3) (0) | 2025.12.10 |
|---|---|
| [개발서적] Clean Architecture 5부(ch20~24) 요약 (2) (1) | 2025.12.10 |
| [개발서적] Clean Architecture 5부(ch15~19) 요약 (1) (0) | 2025.12.10 |
| [개발서적] Clean Architecture 4부(ch12~14) 요약 (0) | 2025.11.26 |
| [개발서적] Clean Architecture 3부(ch7~11) 요약 (1) | 2025.11.16 |