관리 메뉴

KorSA

Clean Architecture (로버트 C. 마틴) - 3 본문

Books/Software Developments

Clean Architecture (로버트 C. 마틴) - 3

Praiv. 2021. 3. 30. 22:52
320x100

이 글은 로버트 C. 마틴의 'Clean Architecture'를 읽고 정리한 문서이며, 총 3부작으로 구성되어 있습니다.

 

Clean Architecture (로버트 C. 마틴) - 1

Clean Architecture (로버트 C. 마틴) - 2

 

[ CHAPTER 5 ] 아키텍처

 

[ 15장 – 아키텍처란 ? ]

#1. 무엇보다도 소프트웨어 아키텍트는 프로그래머이며, 앞으로도 계속 프로그래머로 남는다. 소프트웨어 아키텍트라면 코드에서 탈피하여 고수준의 문제에 집중해야 한다는 거짓말에 절대로 속아 넘어가서는 안 된다. 소프트웨어 아키텍트는 코드와 동떨어져서는 안 된다. 소프트웨어 아키텍트는 최고의 프로그래머이며, 앞으로도 계속 프로그래밍 작업을 맡을 뿐만 아니라 동시에 나머지 팀원들이 생산성을 극대화할 수 있는 설계를 하도록 방향을 이끌어 준다.

 

#2. 아키텍처 안에 담긴 소프트웨어 시스템이 쉽게 개발, 배포, 운영, 유지보수 되도록 만드려면 가능한 한 많은 선택지를, 가능한 한 오래 남겨두는 전략을 따라야 한다.

 

#3. 모든 소프트웨어 시스템은 주요한 두 가지 구성요소로 분해할 수 있다. 바로 정책과 세부사항이다. 정책 요소는 모든 업무 규칙과 업무 절차를 구체화한다. 정책이란 시스템의 진정한 가치가 살아 있는 곳이다. 세부사항은 사람, 외부 시스템, 프로그래머가 정책과 소통할 때 필요한 요소지만, 정책이 가진 행위에는 조금도 영향을 미치지 않는다. 이러한 세부사항에는 입출력 장치, 데이터베이스, 웹 시스템, 서버, 프레임워크, 통신 프로토콜 등이 있다.

 

[ 16장 – 독립성 ]

#1. 시스템을 설계하는 조직이라면 어디든지 그 조직의 의사소통 구조와 동일한 구조의 설계를 만들어 낼 것이다.

 

#2. 좋은 아키텍처는 결합 분리 모드를 선택사항으로 남겨두어서 배포 규모에 따라 가장 적합한 모드를 선택해 사용할 수 있게 만들어 준다.

 

[ 17장 – 경계: 선 긋기 ]

#1. 소프트웨어 아키텍처는 선을 긋는 기술이며, 나는 이러한 선을 경계(boundary)라고 부른다. 경계는 소프트웨어 요소를 서로 분리하고, 경계 한편에 있는 요소가 반대편에 있는 요소를 알지 못하도록 막는다.

 

#2. 관련이 있는 것과 없는 것 사이에 선을 긋는다.

 

#3. 소프트웨어 개발 기술의 역사는 플러그인을 손쉽게 생성하여, 확장 가능하며 유지보수가 쉬운 시스템 아키텍처를 확립할 수 있게 만드는 방법에 대한 이야기다.

 

#4. 경계는 변경의 축이 있는 지점에 그어진다. 경계의 한쪽에 위치한 컴포넌트는 경계 반대편의 컴포넌트와는 다른 속도로, 그리고 다른 이유로 변경된다.

 

#5. 소프트웨어 아키텍처에서 경계선을 그리려면 먼저 시스템을 컴포넌트 단위로 분할해야 한다. 그런 다음 컴포넌트 사이의 화살표가 특정 방향, 즉 핵심 업무를 향하도록 이들 컴포넌트의 소스를 배치한다. 이는 의존성 역전 원칙과 안정된 추상화 원칙을 응용한 것임을 눈치챌 수 있어야 한다. 의존성 화살표는 저수준 세부사항에서 고수준의 추상화를 향하도록 배치된다.

 

[ 18장 – 경계 해부학 ]

#1. 시스템 아키텍처는 일련의 소프트웨어 컴포넌트와 그 컴포넌트들을 분리하는 경계에 의해 정의된다.

 

#2. 로컬 프로세스에서는 고수준 프로세스의 소스 코드가 저수준 프로세스의 이름, 물리 주소, 레지스트리 조회 키를 절대로 포함해서는 안 된다. 저수준 프로세스가 고수준 프로세스의 플러그인이 되도록 만드는 것이 아키텍처 관점의 목표라는 사실을 기억하자.

 

#3. 물리적인 형태를 띠는 가장 강력한 경계는 바로 서비스다. 서비스는 프로세스로, 일반적으로 명령행 또는 그와 동등한 시스템 호출을 통해 구동된다.

 

[ 19장 – 정책과 수준 ]

#1. 소프트웨어 시스템이란 정책을 기술한 것이다. 실제로 컴퓨터 프로그램의 핵심부는 이게 전부다. 컴퓨터 프로그램은 각 입력을 출력으로 변환하는 정책을 상세하게 기술한 설명서다.

 

#2. ‘수준(level)’을 엄밀하게 정의하자면 ‘입력과 출력까지의 거리’다. 시스템의 입력과 출력 모두로부터 멀리 위치할수록 정책의 수준은 높아진다. 입력과 출력을 다루는 정책이라면 시스템에서 최하위 수준에 위치한다.

 

#3. 데이터 흐름과 소스 코드 의존성이 항상 같은 방향을 가리키지는 않는다. 이것이 바로 소프트웨어 아키텍처가 가진 예술 중 하나다. 소스 코드 의존성은 그 수준에 따라 결합되어야 하며, 데이터 흐름을 기준으로 결합되어서는 안 된다.

 

[ 20장 – 업무 규칙 ]

#1. 엔티티는 컴퓨터 시스템 내부의 객체로서, 핵심 업무 데이터를 기반으로 동작하는 일련의 조그만 핵심 업무 규칙을 구체화한다. 엔티티 객체는 핵심 업무 데이터를 직접 포함하거나 핵심 업무 데이터에 매우 쉽게 접근할 수 있다.

 

#2. 유스케이스는 자동화된 시스템이 사용되는 방법을 설명한다. 유스케이스는 사용자가 제공해야 하는 입력, 사용자에게 보여줄 출력, 그리고 해당 출력을 생성하기 위한 처리 단계를 기술한다. 엔티티 내의 핵심 업무 규칙과는 반대로, 유스케이스는 애플리케이션에 특화된 업무 규칙을 설명한다.

 

#3. 유스케이스는 엔티티에 의존한다. 반면 엔티티는 유스케이스에 의존하지 않는다.

 

#4. 업무 규칙은 소프트웨어 시스템이 존재하는 이유다. 업무 규칙은 핵심적인 기능이다. 업무 규칙은 수익을 내고 비용을 줄이는 코드를 수반한다. 업무 규칙은 집안의 가보다. 업무 규칙은 사용자 인터페이스나 데이터베이스와 같은 저수준의 관심사로 인해 오염되어서는 안 되며, 원래 그대로의 모습으로 남아 있어야 한다.

 

[ 21장 – 소리치는 아키텍처 ]

#1. 주택이나 도서관의 계획서가 해당 건축물의 유스케이스에 대해 소리치는 것처럼, 소프트웨어 애플리케이션의 아키텍처도 애플리케이션의 유스케이스에 대해 소리쳐야 한다. 즉, 아키텍처를 보고 무슨 일을 하는 프로그램인지 알 수 있어야 한다.

 

#2. 아키텍처가 유스케이스를 최우선으로 한다면, 그리고 프레임워크와는 적당한 거리를 둔다면, 프레임워크를 전혀 준비하지 않더라도 필요한 유스케이스 전부에 대해 단위 테스트를 할 수 있어야 한다.

 

[ 22장 – 클린 아키텍처 ]

#1. 육각형 아키텍처, DCI, BCE 이들 아키텍처는 세부적인 면에서 다소 차이가 있더라도 모두 같은 목표를 가지고 있는데. 바로 관심사의 분리(separation of concerns)이다. 이들은 모두 소프트웨어를 계층으로 분리함으로써 관심사이 분리라는 목표를 달성할 수 있었다.

 

#2. 소스 코드 의존성은 반드시 안쪽으로, 고수준의 정책을 향해야 한다.

 

#3. 운영 관점에서 특정 애플리케이션에 무언가 변경이 필요하더라도 엔티티 계층에는 절대로 영향을 주어서는 안 된다.

 

#4. 유스케이스는 엔티티로 들어오고 나가는 데이터 흐름을 조정하며, 엔티티가 자신의 핵심 업무 규칙을 사용해서 유스케이스의 목적을 달성하도록 이끈다.

 

#5. 경계를 가로지르는 데이터는 흔히 간단한 데이터 구조로 이루어져 있다. 기본적인 구조체나 간단한 데이터 전송 객체(Data Transfer Object)등 원하는 대로 고를 수 있다.

 

#6. 소프트웨어를 게층으로 분리하고 의존성 규칙을 준수한다면 본질적으로 테스트하기 쉬운 시스템을 만들게 될 것이며, 그에 따른 이점을 누릴 수 있다.

 

[ 23장 – 프레젠터와 험블 객체 ]

#1. 프레젠터는 험블 객체(Humble Object) 패턴을 따른 형태로, 아키텍처 경계를 식별하고 보호하는 데 도움이 된다.

 

#2. 험블 객체 패턴은 디자인 패턴으로, 테스트하기 어려운 행위와 테스트하기 쉬운 행위를 단위 테스트 작성자가 분리하기 쉽게 하는 방법으로 고안되었다. 아이디어는 매우 단순하다. 행위들을 두 개의 모듈 또는 클래스로 나눈다. 이들 모듈 중 하나가 험블(Humble)이다. 가장 기본적인 본질은 남기고, 테스트하기 어려운 행위를 모두 험블 객체로 옮긴다. 나머지 모듈에는 험블 객체에 속하지 않은, 테스트하기 쉬운 행위를 모두 옮긴다.

 

#3. 테스트 용이성은 좋은 아키텍처가 지녀야 할 속성으로 오랫동안 알려져 왔다. 험블 객체 패턴이 좋은 예인데, 행위를 테스트하기 쉬운 부분과 테스트하기 어려운 부분으로 분리하면 아키텍처 경계가 정의되기 때문이다.

 

[ 24장 – 부분적 경계 ]

#1. 아키텍처 경계가 언제, 어디에 존재해야 할지, 그리고 그 경계를 완벽하게 구현할지 아니면 부분적으로 구현할지를 결정하는 일 또한 아키텍트의 역할이다.

 

[ 25장 – 계층과 경계 ]

#1. 오! 소프트웨어 아키텍트여, 당신은 미래를 내다봐야만 한다. 당신은 현명하게 추측해야만 한다. 당신은 비용을 산정하고, 어디에 아키텍처 경계를 둬야 할지, 그리고 완벽하게 구현할 경계는 무엇인지와 부분적으로 구현할 경계와 무시할 경계는 무엇인지를 결정해야만 한다. 하지만 이는 일회성 결정이 아니다. 프로젝트 초반에는 구현할 경계가 무엇인지와 무시할 경계가 무엇인지를 쉽게 결정할 수 없다. 대신 지켜봐야 한다. 시스템이 발전함에 따라 주의를 기울여야 한다. 경계가 필요할 수도 있는 부분에 주목하고, 경계가 존재하지 않아 생기는 마찰의 어렴풋한 첫 조짐을 신중하게 관찰해야 한다.

 

[ 26장 – 메인 컴포넌트 ]

#1. 메인을 애플리케이션의 플러그인이라고 생각하자. 메인은 초기 조건과 설정을 구성하고, 외부 자원을 모두 수집한 후, 제어권을 애플리케이션의 고수준 정책으로 넘기는 플러그인이다.

 

[ 28장 – 테스트 경계 ]

#1. 테스트는 시스템의 일부이며, 아키텍처에도 관여한다. 시스템의 나머지 요소가 아키텍처에 관여하는 것과 동등하게 말이다.

 

#2. 테스트가 지닌 극단적인 고립성이 테스트는 대체로 배포하지 않는다는 사실과 어우러지며, 개발자는 종종 테스트가 시스템의 설계 범위 밖에 있다고 여긴다. 이 관점은 치명적이다. 테스트가 시스템의 설계와 잘 통합되지 않으면, 테스트는 깨지기 쉬워지고, 시스템은 뻣뻣해져서 변경하기가 어려워진다.

 

[ 29장 – 클린 임베디드 아키텍처 ]

#1. 앱이 동작하도록 만드는 것을 나는 개발자용 “앱-티튜드 테스트”라고 부른다. 임베디드 전문인지와 관계없이, 프로그래머가 오직 앱이 동작하도록 만드는 일만 신경 쓴다면 자신의 제품과 고용주에게 몹쓸 짓을 하는 것이다. 프로그램에는 단순히 앱이 동작하도록 만드는 것보다 중요한 것이 훨씬 많다.

 

#2. 임베디드 소프트웨어 개발자가 해야 할 일 하나는 이 경계를 분명하게 만드는 것이다. 소프트웨어와 펌웨어 사이의 경계는 하드웨어 추상화 계층(Hardware Abstraction Layer, HAL) 이라고 부른다. HAL은 새로운 생각이 아니다. PC에는 윈도우가 있기 이전부터 HAL이 있었다.

 

#3. 클린 임베디드 아키텍처에서는 모듈들이 인터페이스를 통해 상호작용하기 때문에 각각의 계층 내부에서 테스트가 가능하다. 각 인터페이스는 타깃과는 별개로 테스트할 수 있도록 해주는 경계층 또는 대체 지점을 제공한다.

 

 

 

 

[ CHATPER 6 세부사항 ]

 

[ 31장 – 웹은 세부사항이다 ]

#1. 연산 능력을 중앙(서버)에 집중하는 방식과 분산(브라우저)하는 방식 사이에서 우리는 끊임없이 움직인다. 그리고 내 생각에 이러한 진동은 한동안 계속될 것이다. IT 역사 전체로 시야를 넓히면 웹은 아무것도 바꾸지 않았다. 웹은 우리가 발버둥치면서 생기는 여느 수많은 진동 중 하나에 불과하다. 이 진동은 우리가 태어나기 전에도 있어 왔고, 우리가 은퇴한 뒤에도 지속될 것이다.

 

[ 32장 – 프레임워크는 세부사항이다 ]

#1. 당신과 프레임워크 제작자 사이의 관계는 놀라울 정도로 비대칭적이다. 당신은 프레임워크를 위해 대단히 큰 헌신을 해야 하지만, 프레임워크 제작자는 당신을 위해 아무런 헌신도 하지 않는다.

 

[ 34장 – 빠져있는 장 ]

#1. 예리한 독자는 이전 다이어그램의 OrdersRepository가 Orders라는 간단한 이름으로 바뀌었음을 눈치챘을 것이다. 이는 도메인 주도 서례라는 세계관에서 비롯된 명명법으로, 도메인 주도 설계에서는 ‘내부’에 존재하는 모든 것의 이름은 반드시 ‘유비쿼터스 도메인 언어’ 관점에서 기술하라고 조언한다. 바꿔 말하면, 도메인에 대해 논의할 때 우리는 ‘주문’에 대해 말하는 것이지, ‘주문 레포지토리’에 대해 말하는 것이 아니다.

 

[ 맺는 글 ]

#1. (Big 프로세스라는 원시의 평원을 어슬렁거리는 모습으로 흔히 목격되는) Big 아키텍처라는 공룡은 익스트림 프로그래밍(Extreme Programming)이라는 소행성으로 인해 완전하게 멸종해버렸다. 그리고 그렇게 우리는 살아남았다. 개발팀은 자유의 몸이 되어 중요한 일에 집중하고, 가치를 더하는 것에 노력을 기울일 수 있었다.

 

#2. Big 아키텍처라는 공룡은 완전히 사라졌고, 작고 날렵하며 충분한 만큼만 설계를 선행한 다음 수없이 리팩터링을 진행하는 영장류가 세상을 대체했다. 소프트웨어 아키텍처는 이제 즉각적으로 반응하게 되었다.

 

#3. 무엇보다 가장 중요한 일은 클린 아키텍처에 대해 이야기하는 것이다. 팀과 함께 클린 아키텍처에 대해 이야기하라. 폭넓은 개발자 커뮤니티와 함께 이야기하라. 품질은 공동의 책임이며, 좋은 아키텍처와 나쁜 아키텍처 사이의 간극에 대해 합의를 이루는 일은 중요하다.

 

#4. 진짜 여정은 지금부터다.

728x90
728x90
Comments