기술

주니어 FE 개발자의 “클린 아키텍쳐” 1회독 후기

ghoon99-dev 2024. 8. 7. 16:32

1장 13p 중.

 

때는 2024년 1월, FE 개발자로서 다니던 회사를 퇴사 후 백수 생활을 즐기고 있었던 시절

방구석에 박혀있던 클린아키텍처: 소프트웨어구조와 설계의 원칙이라는 책을 보게 되었다.

 

개발자라면 언젠가 한 번쯤은 읽어보겠지 라는 막연한 생각 + 들고 다니면 뭔가 멋져보이는 책이라 구매했던 것 같다.

 

들리는 말로는 주니어 때, 중니어(?) 때, 시니어 때 1번씩 보면 볼 때마다 새로운 맛을 느낄 수 있다더라

 

사실 이전부터 업무를 하면서 프로젝트 구조, 모듈 설계에 관심이 많았고,

앞으로 선택의 순간이 찾아왔을 때 적절한 선택지를 제시하고 근거를 들고 싶어 한번 읽어보게 되었다.

 

 

책에 대한 내용은 생략하고 

내가 직접 읽으며 "주니어" "FE 개발자" 관점에서 생각했던 것들, 질문들을 간략히 정리해 보았다.

사실 책에 대한 내용은 거의 없고 책을 읽으며 뻗어나간 생각들이 주요 소재이다.

 

 

내가 느끼기에 많이 등장했던 중요한 키워드

- 의존성

- 계층과 경계

- 컴포넌트

- 결합과 응집

- 정책

- 추상과 인터페이스

 

 

"객체지향 패러다임" 넌 도대체 누구니

역시나 FE 개발에서는 상대적으로 덜 접하게 되는 객체지향 패러다임.

하지만 책을 읽으면서 이것에 대한 개념들이 자주 등장했고 그 개념에 익숙해야 이 책이 더 잘 읽힐 것 같았다.

 

나는 SOLID 하면서 각 원칙들을 머릿속으로 외우는 것 밖에 할 줄 몰랐다. 객체지향적인 코드를 작성해 보고 그 한계와 효용을 몸으로 느끼지 못했어서 익숙하지 않았다.

 

"의존성이 역전된다"라는 것의 의미를 조금 더 명확하게, 예시를 들어 설명할 수 있을 때까지 이해할 필요가 있어 보이는 듯했다.

 

의존성,  한 번도 의식하지 않았던 "import" 문

 

책을 읽다 보니 내가 작성한 코드들의 import 문이 떠오르기 시작했다.

A.js >> import * from "B.js"

 

나에겐 그저 다른 모듈(함수, 리액트 훅, 컴포넌트 등)을 사용하기 위해 자동완성으로 써지는 그런 코드에 불과했다.

 

하지만 모듈 A가 모듈 B를 import 하면 A는 B에 직접적으로 의존하고 있다는 의미였다.

이 직접 참조는 모듈 간의 강한 결합을 나타내며, 모듈 B의 변경이 모듈 A에 영향을 미칠 수 있다는 것을 의미하기도 한다.

 

내가 작성한 (사실 auto import 된) 수많은 import 문들을, 다른 모듈과의 결합도와 연관 지어 생각해 본 적은 적었던 것 같다.

 

 

만약 한 모듈이 많은 다른 모듈에 의해 참조된다면 그 모듈은 중요한 역할을 수행하고 있는 모듈이다.

이런 모듈은 코드의 변경 시 많은 모듈에 영향을 줄 수 있다.

이 모듈은 안정적이고 신뢰성이 높아야 하며, 변경이 필요할 때는 신중해야 한다.

 

특정 관심을 가지고 하나의 책임을 담당한 모듈로서,

 

- 내가 어떤 모듈과 의존 관계를 맺어야 하는지.

- 그것으로 인해 변경의 전파가 얼마나 이루어지는지.

- 나는 책임을 져야 할 모듈이 많은 모듈인지, 무책임한 모듈인지.

 

변경에 유연하게 대응하고, 예측하지 못한 부수효과를 피하고, 흐름을 예측하기 쉽게 설계하기 위해서는 

무심했던 import 문에 한 번쯤은 더 관심을 가지며 개발을 하는 것이 좋을 것 같다는 생각이 들었다.

 

 

 

사용하는 언어가 사고를 지배하는가?

왜인지 모르겠지만 이 책을 읽고 6개월이 지났지만 가장 뚜렷하게 남아있는 건 이것이다. 이 글의 주요 소재이기도 하다.

 

사피어-워프 가설(영어: Sapir–Whorf hypothesis, Whorf hypothesis, Whorfianism, linguistic relativity)
은 한 사람이 세상을 이해하는 방법과 행동이 그 사람이 쓰는 언어의 문법적 체계와 관련이 있다는, 언어학적인 가설이다.
https://ko.wikipedia.org/wiki/사피어-워프_가설

 

 

책을 읽으면서 갑자기 이 유명한 가설이 생각났다.

 

적절한 예시가 맞을지는 모르겠지만

각 언어가 제공하는 음운 체계에 익숙해져 있으면, 그 체계에 없는 소리를 발음하는 데 어려움을 겪게 된다. 

일본어 사용자가 받침발음을 잘 못하는 것, 한국 사람들이 /u/ 발음을 하지 못하는 것을 예시로 들 수 있다.

 

 

마찬가지로, 프로그래밍 언어도 각기 다른 철학과 기능을 통해 개발자에게 특정한 사고방식을 유도할 수 있다.

다른 언어 생태계에서는 당연하게 여겨지는 것들이 한쪽에서는 그렇지 않을 수 있다.

 

한 생태계에 익숙해져 있으면 다른 영역의 사고에 접근하는 것이 힘들 수도 있겠다는 생각이 들었다.

 

 

특히 JS/TS 에서는 interface 가 런타임에 존재하지 않지만 (JS로 변환되며 삭제) , 다른 (JAVA 같은) 언어에서는 런타임에 인터페이스가 존재할 수 있다고 한다.

 

런타임에 인터페이스가 존재할 때, 이것이 어떤 역할을 하며 어떻게 동작하는 원리를 알지 못하니 책의 내용을 이해하는데 어려움을 겪었다.

(런타임에도 인터페이스에 접근해 의존성을 역전시킨다고..?)

 

루비나 파이썬과 같은 동적 타입 언어에서는 소스 코드에 이러한 선언 ( import, use 또는 include) 문 이 존재하지 않는다.
대신 런타임에 추론이 발생한다. 따라서 소스 코드 의존성이 아예 없으며, 결국 재컴파일과 재배포가 필요 없다.
동적 타입 언어를 사용하면 정적 타입 언어를 사용할 때보다 유연하며 결합도가 낮은 시스템을 만들 수 있는 이유는 바로 이 때문이다. 이러한 사실로 인해 ISP를 아키텍처가 아니라, 언어와 관련된 문제라고 결론 내릴 여지가 있다.
p.89 중

 

이런 이야기도 있더라

 

 

자신이 익숙한 언어와 환경에만 머물러 있다면, 새로운 사고방식과 문제 해결 접근법을 접하기 어려울 수 있을 것 같다.

다양한 프로그래밍 언어와 생태계를 경험하는 것은 사고의 확장을 위해 중요하다는 결론을 얻을 수 있었다.

 

 

 

 

그래서 책은 잘 이해했나요?

처음부터 가볍게 읽었고 중간에 자꾸 다른 길로 가버리는 바람에 제대로 이해를 했다고 할 수는 없다.

찍어먹었는데 맛이 아닌 향만 맡은 그런 느낌..

 

무슨 개념을 가지고, 어떠한 관점으로 읽어야 할지 알게 되었으니

2번째로 읽게 되었을 때는 또 다른 인사이트를 얻을 수 있을 것이다.