티스토리 뷰

앱 개발/책

클린 아키텍처

낭초비 2023. 2. 11. 23:56
반응형

소프트웨어 아키텍트가 어떤일을 하는지, 어떻게 하는지, 왜 하는지 궁금해서 클린 코드를 먼저 살까 하다가 이걸 먼저 사게 되었다. 프로그래머가 읽어봐야할 도서 중 하나다 보니, 이것도 다시 보고, 또 보기 위해 구입을 했다. 

 

저자는 클린 코드를 썼던 로버트 C. 마틴.  프로그래밍 관련 도서를 보면 자주 등장하는 이름 있다. 마틴 파울러, 켄트 벡, 에릭 감마, 로버트 C. 마틴. 그래서 익숙한 이름. 

 

   책 내용 정리

아키텍처는 종착지가 아니라 여정에 더 가까우며, 고정된 산출물이 아니라 계속된 탐구 과정에 더 가까움을 이해해야 좋은 아키텍처가 만들어진다. 

 

아키텍처는 구현과 측정을 통해 증명해야 하는 가설이다. 

 

소프트웨어 설계도 마찬가지다. 저수준의 세부사항과 고수준의 구조는 모두 소프트웨어 전체 설계의 구성요소이다. 개별로는 존재할 수 없고, 실제로 이 둘을 구분 짓는 경계는 뚜렷하지 않다. 고수준에서 저수준으로 향하는 의사결정의 연속성만 있을 뿐이다. 

 

소프트웨어 아키텍처의 목표는 필요한 시스템을 만들고 유지 보수하는데 투입되는 인력을 최소화 하는 데 있다. 

 

프로그래밍 패러다임 이란 프로그래밍을 하는 방법으로, 대체로 언어에는 독립적이다. 패러다임은 어떤 프로그래밍 구조를 사용할지, 그리고 언제 이 구조를 사용해야 하는지 결정한다. 

 

구조적 프로그래밍은 제어 흐름의 직접적인 전환에 대한 규칙을 부과한다. 

객체 지향 프로그래미은 제어흐름의 간접적인 전환에 대해 규칙을 부과한다. 

함수형 프로그래밍은 할당문에 대해 규칙을 부과한다. 

 

각 패러다임은 프로그래머에게서 권한을 박탈한다. 어느 패러다임도 새로운 권한을 부여하지 않는다. 각 패러다임은 부정적인 의도를 가지는 일종의 추가적인 규칙을 부과한다. 즉 패러다임은 무엇을 해야할 지를 말하기보다 무엇을 해서는 안 되는지를 말해준다. 세가지 패러다임 각각은 우리에게서 goto문, 함수 포인터, 할당문을 앗아간다. 

 

소스코드 의존성은 소스 코드 사이에 인터페이스를 추가함으로써 방향을 역전 시킬 수 있다. 이러한 접근법을 사용한다면, OO (Object Oriented) 언어로 개발된 시스템을 다루는 소프트웨어 아키텍트는 시스템의 소스 코드 의존성 전부에 대해 방향을 결정할 수 있는 절대적 권한을 갖는다. 즉, 소스 코드 의존성이 제어흐름의 방향과 일치되도록 제한되지 않는다. 소스 코드 의존성을 원하는 방향으로 설정할 수 있다. 이것이 힘이다. 이것이 바로 OO 가 제공하는 힘이다. 

 

소프트웨어, 즉 컴퓨터 프로그램은 순차(sequence), 분기(selection), 반복(iteration), 참조(indirection) 로 구성된다. 그 이상도 이하도 아니다. 

 

SOLID 원칙의 목적은 중간 수준의 소프트웨어 구조가 아래와 같도록 만드는데 있다. 

  • 변경에 유연하다
  • 이해하기 쉽다
  • 많은 소프트웨어 시스템에 사용될 수 있는 컴포넌트의 기반이 된다. 

'중간 수준'이라 함은 프로그래머가 이들 원칙을 모듈 수준에서 작업할 때 적용할 수 있다는 뜻이다. 즉, 코드 수준보다는 조금 상위에서 적용되며 모듈과 컴포넌트 내무에서 사용되는 소프트웨어 구조를 정의 하는데 도움을 준다. 

 

시스템을 확장하기 쉬운 동시에 변경으로 인해 시스템이 너무 많은 영향을 받지 않도록하기 위해서 시스템을 컴포넌트 단위로 분리하고, 저수준 컴포넌트에 발생한 변경으로부터 고수준 컴포넌트를 보호할 수 있는 형태의 의존성 계층 구조가 만들어지도록 해야한다. 

 

안정된 소프트웨어 아키텍처를 위한 구체적인 코딩 실천법

  • 변동성이 큰 구체 클래스를 참조하지 말라. 대신 추상 인터페이스를 참조하라.
  • 변동성이 큰 구체 클래스로부터 파생하지 말라. 정적 타입 언어에서 상속은 소스 코드에 존재하는 모든 관계 중에서 가장 강력한 동시에 뻣뻤해서 변경하기 어렵다. 따라서 상속은 아주 신중하게 사용해야 한다. 
  • 구체 함수를 오버라이드 하지말라.
  • 구체적이며 변동성이 크다면 절대로 그 이름을 언급하지 말라. 

컴포넌트는 배포 단위다. 잘 설계된 컴포넌트라면 반드시 독립적으로 배포 가능한, 따라서 독립적으로 개발 가능한 능력을 갖춰야 한다. 

 

컴포넌트 의존성 다이어그램은 애플리케이션의 빌드 가능성, 유지보수성을 보여주는 지도와 같다. 

 

변경이 쉽지 않은 컴포넌트가 변동이 예상되는 컴포넌트에 의존하게 만들어서는 안된다. 

 

아키텍처의 주된 목적은 시스템의 생명주기를 지원하는 것이다. 좋은 아키텍처는 시스템을 쉽게 이해하고, 쉽게 개발하며, 쉽게 유지보수하고, 또 쉽게 배포하게 해준다. 아키텍처의 궁극적인 목표는 시스템의 수명과 관련된 비용은 최소화하고, 프로그래머의 생산성은 최대화 하는데 있다. 

 

유지보수는 모든 측면에서 봤을 때 소프트웨어 시스템에서 비용이 가장 많이 든다. 

유지보수의 가장 큰 비용은 탐사(spelunking)와 이로 인한 위험부담에 있다. 탐사란 기존 소프트웨어에 새로운 기능을 추가하거나 결함을 수정할 때, 소프트웨어를 파해쳐서 어디를 고치는게 최선인지, 그리고 어떤 전략을 쓰는게 최적일지를 결정할 때 드는 비용이다. 이러한 변경사항을 반영할때 의도치 않은 결함이 발생할 가능성은 항상 존재하며, 이로 인한 위험부담 비용이 추가된다. 주의를 기울여 신중하게 아키텍처를 만들면 이 비용을 크게 줄일 수 있다.

 

모든 소프트웨어 시스템은 주요한 두 가지 구성요소로 분해할 수 있다. 바로 정책(policy)와 세부사항이다.  정책이란 시스템의 진정한 가치가 살이 있는 곳이다. 세부사항은 입출력 장치, 데이터베이스, 웹 시스템, 서버, 프레임워크, 통신 프로토콜 등이 있다. 

 

  • 개발 초기에는 데이터베이스 시스템을 선택할 필요가 없다. 
  • 개발 초기에는 웹 서버를 선택할 필요가 없다.
  • 개발 초기에는 REST를 적용할 필요가 없다. 
  • 개발 초기에는 의존성 주입 프레임워크를 적용할 필요가 없다. 

좋은 아키텍트는 세부사항을 정책으로부터 신중하게 가려내고, 정책이 세부사항과 결합되지 않도록 엄격하게 분리한다. 

 

아키텍트의 최우선 관심사는 유스케이스이며, 아키텍처에서도 유스케이스가 최우선이다. 

 

업무 규칙은 사업적으로 수익을 얻거나 비용을 줄일 수 있는 규칙 또는 절차다. 

핵심 규칙과 핵심 데이터는 본질적으로 결함 되어 있기 때문에 객체로 만들 좋은 후보가 된다. 우리는 이러한 유형의 객체를 엔티티(Entity)라고 하겠다. 

 

엔티티는 수많은 다양한 애플리케이션에서 사용될 수 있도록 일반화된 것이므로, 각 시스템의 입력이나 출력에서 더 멀리 떨어져있다. 유스케이스는 엔티티에 의존한다. 반면, 엔티티는 유스케이스에 의존하지 않는다. 

 

엔티티는 전사적인 핵심 업무 규칙을 캡슐화한다. 엔티티는 메서드를 가지는 객체이거나 일련의 데이터 구조와 함수의 집합일 수 도 있다. 

 

유스케이스 계층의 소프트웨어는 애플리케이션에 특화된 업무 규칙을 포함한다. 또한 시스템의 모든 유스케이스를 캡슐화하고 구현한다. 

 

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

 

소프트웨어 아키텍트여 당신은 미래를 내다봐야만 한다. 당신은 현명하게 추측해야 한다. 당신은 비용을 산정하고, 어디에 아키텍처 경계를 둬야 할지, 그리고 완벽하게 구현할 경계는 무엇인지와 부분적으로 구현할 경계와 무시할 경계는 무엇인지 결정해야만 한다. 하지만 이는 일회성 결정은 아니다. 프로젝트 초반에는 구현할 경계가 무엇인지와 무시할 경계가 무엇인지를 쉽게 결정할 수 없다. 대신 지켜봐야한다. 시스템이 발전함에 따라 주의를 기울여야 한다. 

 

메인은 클린 아키텍처에서 가장 바깥 원에 위치하는, 지저분한 저수준 모듈이라는 점이다. 메인으 고수준의 시스템을 위한 모든 것을 로드한 후, 제어권을 고수준의 시스템에게 넘긴다. 

 

악마는 항상 디테일(구현 세부사항)에 있는 법이며, 이점을 심사숙고하지 않는 다면 마지막 고비에 걸려 넘어지기 십상일 것이다.

 

반응형

'앱 개발 > ' 카테고리의 다른 글

플러터 앱 개발 첫걸음  (0) 2023.09.09
모바일 앱 개발을 위한 다트 & 플러터  (2) 2023.09.09
실용주의 프로그래머  (4) 2023.01.28
오브젝트 (코드로 이해하는 객체지향 설계)  (0) 2022.07.02
Refactoring  (0) 2022.02.11
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
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 31
글 보관함