본문으로 건너뛰기

2023.07.06

· 약 16분

1. 만들면서 배우는 클린 아키텍처 요약 (1,2,3장)

우리는 모두 낮은 개발 비용으로 유연하고 적응이 쉬운 소프트웨어 아키텍처를 구축하고자 한다. 그러나 불합리한 기한과 쉬워보이는 지름길은 이러한 아키텍처를 구축하는 것을 매우 어렵게 만든다.

어떤 지름길이 어떤 종류의 기술 부채를 만들고, 어떤 경우에 이러한 부채를 기꺼이 질 가치가 있는지 배운다.

'지름길 모드'는 '깨진 창문 이론'과 같다. 아키텍처의 '지름길 모드'를 끄고 싶다면, 적어도 추가적인 아키텍처 규칙을 강제하지 않는 한 계층은 최선의 선택은 아니다. 그리고 여기서 '강제한다'는 것은 시니어 개발자가 코드 리뷰를 한다는 의미가 아니라 해당 규칙이 깨졌을 때 빌드가 실패하도록 만드는 규칙을 의미한다.

아주 엄격한 자기 훈련 없이는 시간이 지날수록 품질이 저하되고 유지보수하기가 어려워지기 쉽다. 이러한 자기 훈련은 보통 프로젝트 매니저가 개발팀에 새로운 마감일을 설정할 때마다 조금씩 느슨해지기 마련이다.

새 프로젝트에거 가장 먼저 제대로 만들려고 하는 것은 패키지 구조다. 프로젝트에서 계속 사용할 괜찮아 보이는 구조를 잡는다. 그리고 나서 프로젝트가 진행될수록 점점 바빠지고 패키지 구조는 짜임새 없는 엉망진창 코드를 그럴싸하게 보이게 만드는 껍데기일 뿐이라는 점을 깨닫게 된다. 한 패키지에 있는 클래스들이 불러오지 말아야 할 다른 패키지에 있는 클래스들을 불러오게 된다.

계층으로 구성하기: 애플리케이션의 기능 조각이나 특성을 구분 짓는 패키지 경계가 없다. 애플리케이션이 어떤 유스케이스들을 제공하는지 파악할 수 없다. 특정 기능을 찾기 위해서는 어떤 서비스가 이를 구현했는지 추측해야 하고, 해당 서비스 내의 어떤 메서드가 그에 대한 책임을 수행하는지 찾아야 한다. 패키지 구조를 통해서 우리가 목표로 하는 아키텍처를 파악할 수 없다. 육각형 아키텍처 스타일을 따랐다고 추측할 수는 있다.

기능으로 구성하기: 패키지 간의 경계를 강화할 수 있다. 유스케이스를 구현한 코드는 클래스명만으로도 찾을 수 있게 됐다. 애플리케이션의 기능을 코드를 통해 볼 수 있게 만드는 것을 가리켜 로버트 마틴이 '소리치는 아키텍처'라고 명명한 바 있다. 왜냐하면 코드가 그 의도를 우리에게 소리치고 있기 때문이다. 그러나 기능에 의한 패키징 방식은 사실 계층에 의한 패키징 방식보다 아키텍처의 가시성을 훨씬 더 떨어뜨린다. 아키텍처 다이어그램에서 어떤 박스를 가리켰을 때 코드의 어떤 부분이 해당 박스를 책임지는지를 바로 알 수 있다면 좋을 것이다.

아키텍처적으로 표현력 있는 패키지 구조: 패키지 구조는 이른바 '아키텍처 - 코드 갭' 혹은 '모델 - 코드 갭'을 효과적으로 다룰 수 있는 강력한 요소다. 만약 패키지 구조가 아키텍처를 반영할 수 없다면 시간이 지남에 따라 코드는 점점 목표하던 아키텍처로부터 멀어지게 될 것이다. 이처럼 표현력 있는 패키지 구조는 아키텍처에 대한 적극적인 사고를 촉진한다. 많은 패키지가 생기고, 현재 작업 중인 코드를 어떤 패키지에 넣어야 할지 계속 생각해야하기 때문이다. 모든 구조와 마찬가지로 패키지 구조를 소프트웨어 프로젝트 내내 유지하기 위해서는 지켜야 할 규칙이 있다. 또한 패키지 구조가 적합하지 않아서 어쩔 수 없이 아키텍처-코드 갭을 넓히고 아키텍처를 반영하지 않는 패키지를 만들어야 하는 경우도 생길 수 있다. 완벽한 방법은 없다. 그러나 표현력 있는 패키지 구조는 적어도 코드와 아키텍처 간의 갭을 줄일 수 있게 해준다.

실제 코드 구조를 최대한 우리가 목표로 하는 아키텍처에 가깝게 만들어주는 육각형 아키텍처의 패키지 구조를 살펴봤다. 코드에서 아키텍처의 특정 요소를 찾으려면 이제 아키텍처 다이어그램의 박스 이름을 따라 패키지 구조를 탐색하면 된다. 이로써 의사소통, 개발, 유지보수 모두가 조금 더 수월해진다.

2. 폴더링에 대하여 마구잡이로 쓰는 나의 생각

사람들은 기본이 중요하다라는걸 말하면서도 쉽게 넘어간다. 제대로 이해하지 않고 음~ 그렇구나 라고 알고 넘어간다. 소프트웨어 기술 서적을 읽을 때 항상 기본에 대한 글이 있는데도 빠르게 넘어가고 심화 부분과 기법들을 수록되어있는 장으로 넘어간다. 하지만 기본은 정말 중요하다.

소프트웨어 개발 서적에서 항상 나오는 말이 있다. "유지보수가 잘되는 소프트웨어를 개발해야한다." 대부분의 기술서적들이 유지보수에 대한 내용을 다룬다. 여기서 사람들은 SOLID를 배우고 의존성 주입을 배우고 아키텍처를 배운다. 이런 내용들은 매우 종요한 내용이라는 것에 매우 동의한다. 하지만 이것보다 중요하고 기본적인 것은 클린코드다. 유지보수하기 쉬운 소프트웨어의 기본 첫번째 조건은 알기 쉬운 변수명과 함수명 그리고 파일을 잘 분리하고 위치시키는 것이다.

본인의 코드를 두고 잘 고민해봤으면 좋겠다. 나는 지금 이 프로젝트를 개발한 당사자이지만 내가 아닌 다른 사람(혹은 1년후의 본인)이 프로젝트에 투입되었을 때 변수명, 함수명을 보고 어떤 변수이고 함수인지 알 수 있겠는가? 또는 새로운 기능이나 기존 기능을 수정해야하는 task를 받았을 때 수정해야하는 파일의 위치를 빠르게 찾아갈 수 있겠는가? 여기에 당당하게 그렇다고 말할 수 있는 사람은 많이 없을 것 같다. (본인이 작성한 코드를 사랑해서, 오랫동안 작업하여 편견에 휩싸여 대답하지는 않았는지 다시 돌아보길 바란다.)

누구나 알지만 쉽게 넘어가는 부분들을 매우 중요한 부분이라고 생각하고 행동해줬으면 좋겠다.

  • 프로젝트를 처음 시작할 때 가장 먼저 하는것이 폴더 구조다.

  • 새로운 요구사항 또는 이유로 폴더를 만들어야 할때

    • 내가 좋아보이고 알기 쉬운 구조로 만드는 것이 아닌 객관적이고 남들이 봤을 때 알기 쉽고 찾아가기 쉬운 폴더 구조를 만드는데 집중해야 한다. 이런 기준으로 폴더를 만들고 위치시켰으면 좋겠다. 문서를 읽거나 파일을 폴더에 배치시키거나 폴더를 찾아갈 때 창의적 혹은 추론하여 찾아가지 않도록. 폴더들이 "나 여기있어!" 소리치고 있도록. 이전에 개발한 개발자가 코드리뷰로 폴더 위치가 잘못되었다고 말하는 상황이 왔다면 잘못 작성되고 있는 것이다. 이는 주관적인 관점에서 폴더링을 한 것일 수도 있고 사람마다 관점에 따라 다르게 폴더링을 했다고도 할 수 있다.
    • 엄격한 자기 훈련이 필요한 상태는 시간이 지날수록 품질이 저하되고 유지보수하기 어려워지기 시작한다. 처음 설계한 개발자가 프로젝트에서 떠나버리면 여러 철학과 개념이 혼재된 카오스가 될 것이다.
  • 우리가 해야할 일은

    • 코드 수정해야할 일이 있을 때 빠르게 해당 파일을 찾아갈 수 있도록 개발해야 한다.
    • 주관적인 생각이나 소수의 집단이 알고 있는 철학이나 방법론을 적용한 폴더링은 피해야한다. -> 이것을 판단할 수 있는건 새로운 누군가가 코드를 작성했을 때 코드리뷰로 잘못된 폴더에 코드를 작성했다고 알려주는 것, 새로운 누군가가 새로운 파일을 만들었을 때 어느 폴더에 넣어야 하는지 창의적, 추론을 하면서 폴더에 집에 넣는 상황이 발생하는 것이다.
  • 단편적으로 생각해서, 현재 상황을 기반 또는 프로젝트에 대한 이해도가 높은 상태에서 폴더 구조를 짠다면 주관이 많이 반영된것이기 때문에 경계하자. 코드는 쓰는 시간보다 찾고 읽는 시간이 훨씬 많다. 빨리 찾고 읽을 수 있도록 배치해야한다.

  • 위에서 기준을 계속 말했지만 반영되었으면 좋을 세부적인 부분 몇 개만 언급하면

    • 연관된 것은 같은 폴더에 두었으면 좋겠습니다.
      • 이전 회사에서는 components > dialog > SignUpDialog, WithdrawInfoCreateDialog, WithdrawEditCreateDialog, CashReceiptEditDialog 이런식이였습니다. 이렇게 폴더 구조를 짜면 코드를 위에서 끝까지 코드를 읽어가면서 내가 수정해야할 코드를 찾게 됩니다. 도메인(기능) 별로 묶여야 합니다. components > withdraw > WithdrawInfoSection, WithdrawInfoCreateDialog, WithdrawEditCreateDialog 연관된 것들 끼리 묶여있어야 찾기 쉽고, 관련 코드를 찾을 때 여러 폴더를 이동하지 않아도 됩니다. Dialog와 페이지가 props로 데이터를 주고 받기 때문에 멀리 떨어져 있는 파일들을 왔다갔다하면서 코드 수정해야합니다. 가까운 것은 가까이 위치시켜야합니다. 같이 코드수정을 해야하는 파일들은 같은 폴더에 위치시켜야 합니다.
    • 폴더링에 주간이 관여되지 않았으면 좋겠습니다.
      • 나만이 알고 있는 정보, 어느 블로그나 아티클을 보고 폴더링을 하거나 프로젝트에 대한 도메인 지식이 풍부한 상태를 기반으로 폴더링을 하게되면 프로젝트에 처음 들어온 사람이나 익숙치 않은 사람들은 창의력과 추론을 바탕으로 파일을 위치시키게 되고 이를 코드 리뷰에서 피드백이 꼭 필요하게 됩니다. 시간이 지날수록 품질이 저하되고 유지보수하기가 어려워지기 쉬워질 겁니다. 엄격한 훈련이 필요하지 않도록 폴더링을 해야합니다.