도서 리뷰 시리즈 - 클린 아키텍처
출처
『클린 아키텍처』 로버트 C. 마틴 저/송준이 역 | 인사이트(insight) | 2019년 08월
한 줄 리뷰
좋은 설계에 대한 고민을 할 때 스승이 되어주는 도서
클린 아키텍처 일부 요약
아키텍처란
아키텍처와 설계를 구분하면 이런 형태로 해석할 때가 있다.
- 아키텍처: 저수준의 세부사항과는 분리된 고수준의 무언가를 가리킬 때 사용
- 설계: 저수준의 구조 또는 결정사항들을 의미할 때가 많다.
하지만 실제로 이들을 구분 짖는 경계는 뚜렷하지 않다. 고수준에서 저수준으로 향하는 의사결정의 연속성만이 있을 뿐이다.
저수준의 세부사항과 고수준의 구조는 모두 소프트웨어 전체 설계의 구성요소이다.
소프트웨어 아키텍처의 목표는 필요한 시스템을 만들고 유지 보수하는 데 투입되는 인력을 최소화한다.
설계 품질을 재는 척도는 비용이 낮고 시스템의 수명이 다할 때까지 낮게 유지할 수 있다면 좋은 설계이다.
행위와 구조
- 행위: 기능 명세서나 요구사항을 구현하고, 버그를 수정하는 일
- 구조: 기능에 대한 생각을 바꾸면 이러한 변경 사항을 간단하고 쉽게 적용할 수 있게 하는 것
행위와 구조 둘 중 하나만 집중하게 되면 짧은 생명주기의 소프트웨어를 생산하게 된다.
프로그래밍 패러다임
패러다임은 무엇을 해야 할지를 말하기보다는 무엇을 해서는 안 되는 지를 말해준다.
- 구조적 프로그래밍: 제어 흐름이 직접적인 전환에 대해 규칙을 부과한다.
- 1968년 에츠히르 비버 데이크스트라
- 무분별한 goto는 해롭다. if/then/else, do/while/until로 대체
- 객체지향 프로그래밍: 제어 흐름의 간접적인 전환에 대한 규칙을 부과한다.
- 1966년 요한달, 크리스덴 니가드. ALGOL 언어
- 함수 호출 스택 프레임을 힙으로 옮기면, 함수호출이 반환된 이후에도 함수에서 선언된 지역변수가 오랫동안 유지될 수 있음을 발견했다. 이러한 함수가 클래스의 생성자가 되었고, 지역 변수는 인스턴스 변수, 그리고 중첩함수는 메서드가 되었다.
- 함수형 프로그래밍: 할당문에 대해 규칙을 부과한다.
- 1958년 존 매카시. LISP 언어
- LIST 언어의 근간이 되는 개념이 바로 람다 계산법이다.
- 람다 계산법의 기초가 되는 개념을 불변성으로 심볼의 값이 변경되지 않는다는 개념이다.
- 이는 함수형 언어에서는 할당문이 전혀 없다는 뜻이기도 한다.(제공하지만 굉장히 까다롭다.)
SOLID 원칙
많은 사람과 소프트웨어 설계 원칙에 관해 토론하는 과정에서 이들 원칙을 모으기 시작했다. 원칙들을 교체/변경/삭제/병합한 결과 최종본이 나왔다.
- SRP: 단일 책임 원칙 (Single Responsibility Principle)
- 소프트웨어 시스템이 가질 수 있는 최적의 구조는 시스템을 만드는 조직의 사회적 구조에 커다란 영향을 받는다. 따라서 각 소프트웨어 모듈은 변경의 이유가 단 하나여야만 한다.
- OCP: 개방-패쇄 원칙 (Open-Closed Principle)
- 기존 코드를 수정하기보다는 반드시 새로운 코드를 추가하는 방식으로 시스템의 행위를 변경할 수 있도록 설계해야만 소프트웨어 시스템을 쉽게 변경할 수 있다.
- LSP: 리스코프 치환 원칙 (Liskov Substitution Principle)
- Liskov가 정의한 하위 타입에 관한 유명한 원칙
- 상호 대체 가능한 구성요소를 이용해 소프트웨어 시스템을 만들수 있으려면, 이들 구성요소는 반드시 서로 치환 가능해야 한다는 계약을 반드시 지켜야 한다.
- ISP: 인터페이스 분리 원칙 (Interface Segregation Principle)
- 사용하지 않는 것에 의존하지 않아야 한다.
- DIP: 의존성 역전 원칙 (Dependency Inversion Principle)
- 고수준 정책을 구현하는 코드는 저수준 세부사항을 구현하는 코드에 절대로 의존해서는 안 된다. 대신 세부사항이 정책에 의존해야 한다.
컴포넌트 응집도 원칙
- REP: 재사용/릴리즈 등가 원칙 (Reuse/Release Equivalence Principle)
- 재사용단위는 릴리즈 단위와 같다.
- CCP: 공통 패쇄 원칙 (Common Closure Principle)
- 동일한 이유로 동일한 시점에 변경되는 클래스를 같은 컴포넌트로 묶어라. 서로 다른 시점에 다른 이유로 변경되는 클래스는 다른 컴포넌트로 분리하라.
- CRP: 공통 재사용 원칙 (Common Reuse Principle)
- 컴포넌트 사용자들을 필요하지 않은 것에 의존하게 강요하지 마라.
컴포넌트 결합 원칙
- ADP: 의존성 비순환 원칙 (Acycle Dependencies Principle)
- 컴포넌트 의존성 그래프에 순환이 있어서는 안 된다.
- SDP: 안정된 의존성 원칙 (Stable Dependencies Principle)
- 안정성의 방향으로 의존하라.
- SAP: 안정된 추상화 원칙 (Stable Abstractions Principle)
- 컴포넌트는 안정된 정도만큼만 추상화되어야 한다.