본문 바로가기
아키텍처

클린 아키텍처 - Clean Architecture

by vapor3965 2024. 3. 27.

목차

     

      오랜만에 개발관련 책을 읽었다.

      변명이라면 변명이겠지만.. 일만 하다보니 업무관련된 것에는 공부를 잘안했다.

      그래서 그런지 플러터 같은 업무와 관련없는것에 잠깐 빠졌었는데, 우리팀으로 합류한 팀원덕분에 클린아키텍처 책을 읽을 동기부여를 얻었다. 동기부여가 궁금하다면..

      동기부여

      워낙 클린아키텍처 이름을 많이들었고, 봐야지, 봐야지만 해왔었고, 이름그대로.. 클---린 한 아키텍처인가보다. 라고만 생각해왔었다.
      VIPER, RIBs 등 유명한 패턴들이 있었고, 이것들도 공부해야지~만 생각했었다. (RIBs는 잠깐 강좌만 들어봤었다.)
      동기부여를 주신 팀원분이 클린아키텍처 란 개념서 같은 느낌이고, 이를 각기 나름대로 재해석하여 만든 아키텍처가 VIPER, RIBs, TCA 등이 있다고 한다.
      여기서부터 머리가 띵하면서 클린아키텍처를 읽고싶은 동기부여를 얻었다.
      그래서 나는 이책을 읽고, 재해석하여 만든 아키텍처 패턴, VIPER, RIBs, TCA 등을 알아보려고 한다.

       

      이책을 요약하자면..

      소프트웨어 프로그램 요소를, 하나의 책임을 가지는 클래스, 컴포넌트별로 구분하고, 컴포넌트끼리는 의존성을 분리한다.

      앗, 참고로 이 글은 클라이언트 관점으로 작성되었다. ( 아무래도 내가 클라이언트 개발자이므로. )
      클린아키텍처 책은 클라이언트, 서버 상관없이 큰 관점으로 작성되긴했다. ( 서버중심같기도 )

      클린아키텍처란 ?

      클린아키텍처의 목표가 쉬운 개발 및 배포, 유지보수를 줄이는것이라고 한다.
      클린아키텍처란 종착지가 아니라, 목표를 달성하기 위해 끊임없이 토론하는 일련의 과정이라고 한다.

      보호

      그래서 이책의 개념대로 소프트웨어 시스템의 구성요소들을 컴포넌트단위별로 구분하고, 이들을 클린아키텍처의 계층으로 나누어서 ( = 고수준, 저수준으로 나누어 ) 고수준보호하도록 의존성을 설계하는 것. ( = 저수준의 변경이 고수준에 영향이 없도록 )

      • 보호하기 위해서는 고수준은 저수준의 세부사항을 몰라야한다.
        • 저수준을 사용해야한다면, 의존성을 분리하여 구현체(세부사항)를 모르도록한다.
        • 저수준이 고수준을 사용해야한다면, 고수준의 안정성은 높아지지만 변경에 유연하도록 추상화를 하여 저수준이 고수준의 추상화를 의존하도록 한다.

      변경이 있는것에 의존하지 않는다.

      목표를 달성하기 위해서 가장큰 핵심은 변경에 유연하게 대응하는것이라고 한다.
      변경에 유연하려면 결국 핵심은 의존성을 분리하는것이다.

      • 다르게 말하면, 변경이 있는것에 의존하지 않아야한다.

      (A->B) = A가 B에 의존한다는 의미는, A가 B를 사용하겠다는 의미다.
      다르게 말하면, B의 변경이 있을 때 A에 영향을 줄 수 있다는 의미다.
      이 문구가 이 책을 관통하는 핵심 문구라고 생각한다.
      따라서 B의 변경이 있을때 A에 영향을 최소화하는게 이 책의 목표다.

      • 왜냐하면, 소프트웨어 자체가 변경을 쉽게 하기 위해서 만든것이고, 결국 개발자가 할 일은 프로그래밍을 통해서 기능을 추가하고, 제거하고, 변경하는것이다. 코드는 시간이 지날수록 쌓일거고, 기능도 복잡해질것이다.
      • 동작하게끔만 만든 코드는 결국 기능을 추가하거나, 수정하는 일에 엄청난 사이드이팩트가 발생할수 있고, 방지하기 위하여 관련된 코드들을 탐사하는 시간도 많이 소요될것이다. 이러한 비용이 너무나 커서 결국 손을 못대는 상황이 올수있다.

      B의 변경이 있을때 A에 영향을 어떻게 최소화할수 있을까?
      B는 C라는 인터페이스,프로토콜을 구현하고, A는 C에 의존하도록 한다.
      A -> C <- B ( 인터페이스,프로토콜이 변경되면 B도 영향을 미치기때문 )
      그러면 B의 구현체는 더이상 A에게 영향이 없게된다.
      이는 의존성이 역전됐다라고 말하며, 의존성이 분리되었다고 말한다.

      • B가 A에 의존한다라고도 표현한다.
      • 다르게 말하면, B의 변경이 A에 영향을 최소화하려면 B가 A에 의존하면 된다. 하지만 A가 B를 사용하려 한다면, 인터페이스,프로토콜을 두도록 한다.

      결국 핵심은 변경이 있는것에 의존하지 않아야한다.
      이는 다르게 말하면, 고수준은 저수준에 의존하지 않아야하고,
      의존하지 않는다는것은 구현체를 모른다라고 의미할수있다.
      정책은 세부사항을 몰라야한다.
      정책은 고수준, 업무규칙을 의미하고, 세부사항은 구현체를 의미한다.

      • 뷰도 세부사항.
        고수준컴포넌트는 저수준구현체를 몰라야하고,
        고수준컴포넌트는 보호받아야한다
      • 보호 = 저수준구현체의 변경으로부터 영향을 최소화

      의존성 분리로 얻을수 있는 이점

      변경에 따른 영향을 최소화할 수 있는데, 작은 클래스 뿐만아니라, 넓은 관점에서 보면 라이브러리의존성도 떨어트릴 수 있다. 즉 라이브러리를 쉽게 교체가 가능해진다.

      더 넓은 관점에서 보면 프레임워크에 대한 의존성도 떨어트릴 수 있다.

      더 넓게보면 애플리케이션도 교체할 수 있다. RIBs 아키텍처가 그러하다. 안드로이드, ios 둘다 동일한 구조로 사용할 수 있다.

      이 책을 추천한다면 ?

      취업전, 취업후 모든 사람들한테 추천한다.
      취업전인 사람들에게는 프로그램이 어떤 요소들로 이루어지고, 어떤것이 많이 변경되는지, 무엇을 신경써야하는지, 등을 미리 엿볼수 있는 점에서 추천드리고 싶다.

      취업후 사람들(나)에게는 이 책의 내용을 현재 내 업무와도 연관지어서 생각해볼 수 있고, 배울점이 많다고 느꼈다.

      책 정리

      1부 클린아키텍처 개념

      추상적인 클린아키텍처 개념과, 필요성을 배워본다.

      2부 패러다임

      클린아키텍처도 결국 코딩의 일환이고, 코딩의 방법론인 패러다임을 찍먹해본다.
      (구조적프로그래밍, 객체지향프로그래밍, 함수형프로그래밍)

      - ( 개인적으로 신기했던게, 구조적프로그래밍을 창시한 네덜란드 개발자 데이크스트라가, 최단경로 알고리즘, 다익스트라 알고리즘의 이름이 데이크스트라였다..!  데이크스트라가 원래는 수학자에서 프로그래머로 전향하신... ) 

      3부 SOLID

      클린아키텍처의 좋은 재료로써 코딩의 원칙들을 배워본다.
      핵심은 단일책임원칙과 의존성 분리.

      4부 컴포넌트 개념

      좀 더 넓은 관점에서 독립적으로 배포 가능한 최소단위의 컴포넌트 개념을 배운다.
      그래서 컴포넌트들을 어떻게 나눌수있는지 배워본다.

      5부 클린아키텍처

      아래 개념, 클린 아키텍처라고 부를 수 있는 구성방법을 배워본다.
      ( 내가 이해한바로는, 컴포넌트들을 아래처럼 나눠볼 수 있는 것 ? )

      유스케이스, 엔티티는 시스템의 의도를 보여줄 수 있어야한다.

      6부 세부사항

      이 책의 핵심이 정책은 세부사항을 몰라야한다인데, 즉 세부사항이 어떤것들인지 배워본다.
      ( 데이터베이스, 웹, GUI, 프레임워크 )

      7부 부록

      스킵! ㅎ

      etc...

      생각해볼만 한 문구

      지난 반세기동안 배운것은 해야할 것이 아닌, "하지 말아야할 것"

      패러다임은 우리에게 권한을 부여하기보다는 권한을 제한한다.

      개방폐쇄원칙은 수십년전부터 적용됐던 원칙이다. (입출력장치가 공통된 인터페이스를 사용하도록 한것)

      안정성이 높다는것은 변경이 어렵다는 것, 즉 나를 의존하는 것들이 많다는 것.

      • 그래서 고수준계층일수록 안정성이 높아질것이고, 추상화가 반드시 필요하다.

      가변적(변수)인게 모든 문제의 화근이다.

      • 모든 동시성 문제는 변수로부터 발생

      개인적 생각

      ViewModel 대한 생각

      굉장히 부끄럽지만.. 뷰모델에 대해 다시생각하게 되었다.
      뷰모델뷰모델.. 뷰를 위한 모델이라고만 생각하고, 뷰컨트롤러안에서 뷰들이 참조하는 모델들을 정리한 객체라고만 생각해왔다. 거기에 인터렉터단의 API컨트롤러도 포함시켰다.

      근데 이책을 읽으면서 뷰는 가장 하위의 세부사항이므로 몰라도되는 부분이고, 변경이 많은 컴포넌트중 하나라고 한다. (실제로도 업무에서도 그렇고 )
      그러므로 뷰는 언제든지 교체가 가능하고, 그보다 높은 고수준객체에는 영향이 없어야할것이다.
      뷰모델이 그 중간다리 역할을 한다라고 이해가 되었고, 뷰모델만 가지고 뷰를 교체할수 있어야한다고 생각이 들었다. ( 팀원분에게도 질문했는데 그렇다라고 생각하심 )
      아, 내가 뷰모델을 반만 이해했구나 라고 들었다.
      다음부터 리팩토링하거나 코드를 작성할때는 뷰모델만 보고도 뷰의 기능들을 이해할 수 있도록, 액션의 행위관련된 코드도 넣어줘야겠다.
      ( 역시 공부를 해야해 ㅠㅠ )

      View와 Data의 관계

      당연하겠지만 View에서 Data (모델)를 참조하여 뷰를 그려냈다.
      이 책의 SOLID 원칙 - OCD ( 개방폐쇄원칙)에서 A의 변경이 B에 영향을 받지않도록 하려면, A가 B에 의존해야한다. 한다고 하는데, 이 개념이 View - Data의 관계에도 정확히 대응된다는점이 신기했다. 아무런 생각없이 당연하게만 사용하던것이 이 책의 기본 개념과도 맞다는게...
      View가 아무리 변경이되도 Data에는 영향이 없을것이다. Data는 View를 모르니까.

      클라이언트 개발에서 우선순위 ?

      나는 클라이언트 개발자이고, GUI가 보여지는게 많다보니, GUI가 핵심이면 안되는것 같으면서도 GUI가 핵심인것같은데..... 하는 긴가민가했다.
      암튼 이책에서도 나같은 생각을 하는 사람들을 위해 일침을 날려주셨는데 ㅎ
      GUI는 세부사항, 저수준이라고 한다.
      그래서 화면전환의 흐름과 의존성주입등을 중점으로 생각해보고, 관련 코드들도 참고하고 하려고한다.

      🧐 네트워킹 작업들은 어디에 속하나..

      네트워킹작업에 용이하도록 컴포넌트로 만들수 있을텐데, 이 컴포넌트는 클린아키텍처 계층으로 봤을때 어디에 속해야하나.. 유스케이스인가 ? 아니면 인터페이스 어뎁터 계층인가 ? 흐음.. 사실 어느 계층에 속하는 부분은 그렇-게 중요한 것 같지는 않은데. 앱의 고수준에는 아니면서도 뷰의 저수준도 아닌 중간단계일듯.

      🧐 엔티티와 데이터베이스

      엔티티의 핵심업무규칙데이터, 즉 앱 전역에서 쓰이는 데이터는 데이터베이스에도 저장이 될텐데,
      데이터베이스에서 불러올때 객체화 시켜서 가져오고, 이것을 유스케이스단까지 끌어올려도되나 ?
      구현체말고 프로토콜로 추상화시킨걸로 끌어올리면 되나 ?
      아니면... 각 계층, 데이터전달 과정마다 각기 다른 타입으로 해서 매번 변환해줘야하나..? 흠 ..

      앞으로..

      이 책을 기반으로하여 만들어진 구조들을 알아보려고 한다.
      우선은 깃헙의 별많은 순으로 읽어봐야겠다. ㅎ

      요새 플러터로 만든 가계부앱이 있는데, 이걸 좀더 클린아키텍처 기반하여 리팩토링을 해볼까... 한다. 아니 출시부터 해야하는데.ㅠ 요새 드는 생각은 직장인들이 사이드플젝하거나 따로 공부하는 사람들이 참 대단한것 같다. 시간이 없는건 아니고, 부족할뿐..

      댓글