ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 클린 아키텍처, 소프트웨어 구조와 설계의 원칙(로버트C.마틴)
    책/인상깊게_읽은_책들 2022. 1. 4. 14:45

    클린 아키텍처라는 제목만으로도 읽기에 어려울 수 있겠다는 생각이 드는 책이었다. 미뤄뒀던 책을 읽어보게 되었는데 읽으면서 느끼는 점이 너무 많았다. 물론 이 책의 모든 내용을 이해했다고는 할 수 없겠으나 내가 책에서 공감되었던 내용, 충격적으로 다가왔던 내용들 위주로 기록에 남겨보려고 한다. 생각보다 너무 재밌었고, 주변에 추천해가며 읽었던 책이다. 어떻게 코드를 짜야할까, 어떤 구조로 구성해야할지 고민을 조금이라도 했던 사람이라면 매우 추천하고 싶다.

    Quotes

    패러다임

    구조적 프로그래밍은 제어흐름의 직접적인 전환에 대해 규칙을 부과한다.
    객체 지향 프로그래밍은 제어흐름의 간접적인 전환에 대해 규칙을 부과한다.
    함수형 프로그래밍은 할당문에 대해 규칙을 부과한다.
    (26~27pg)

    각 패러다음은 프로그래머에서 권한을 박탈한다고 한다. 새로운 권한을 부여하는 것이 아니라 부정적인 의도를 가지는 일종의 추가적인 규칙을 부과한다고 한다. 패러다임은 새로운 무언가 새로운 방식이라고 생각했다. 하지만 규칙을 부과하여 프로그래머가 특정 방식으로 개발하도록 부여하는 규칙이었다.

     

    경계를 뛰어넘기 위해 객체 지향과 다형성을, 데이터 위치와 접근에 대해 함수형 프로그래밍을, 알고리즘으로 구조적 프로그래밍을 사용한다고 한다. 각각의 패러다임은 구분을 지을 수 있다기 보다는 아키텍처를 이루는 규칙들이라는 생각이 들었다. 취업준비를 하면서 알고리즘 공부를 좋아하지 않았다. 아마 알고리즘을 공부한다는 것은 구조적 프로그래밍의 방식을 간접적으로 테스트하는 것이 아닐까라는 생각이 들었다.

    구조적 프로그래밍

    데이크스트라는 "테스트는 버그가 있음을 보여줄 뿐, 버그가 없음을 보여줄 수는 없다"고 말한 적이 있다. 다시 말해 프로그램이 잘못되었음을 테스트를 통해 증명할 수는 있지만, 프로그램이 맞다고 증명할 수는 없다. 테스트에 충분한 노력을 들였다면 테스트가 보장할 수 있는 것은 프로그램이 목표에 부합할 만큼은 충분히 참이라고 여길 수 있게 해주는 것이 전부다.

    소프트웨어 개발은 수학적인 시도가 아니라는 사실이다. 오히려 소프트웨어는 과학과 같다. 최선을 다하더라도 올바르지 않음을 증명하는데 실패함으로써 올바름을 보여주기 때문이다.
    (35pg)

    프로젝트를 하며 테스트 코드를 작성하면서 테스트 코드가 통과한다고 프로그램의 버그 가능성이 없다는 것을 증명할 수는 없다고 생각했다. 따라서 테스트 코드는 이 서비스가 지켜야할 최소한의 기능을 보장하기 위한 도구라고 생각했다. 그러면서 기본적인 내용과 정책정도만 테스트로 작성되면 된다고 생각했다. (예외 정책들까지만 테스트할 뿐 엣지 케이스까지 테스트코드를 작성할 필요가 있을까라는 생각을 했었다.) 이렇게 테스트 코드는 꼭 필요하지만 서비스의 안정성을 보장하지는 않는다고 생각했다.

     

    인용한 내용 또한 버그가 있음을 통해 개발시에 해당 부분의 버그를 발생하게 하지 않을 뿐이라는 내용이라는 것이다. 이렇게 아님을 증명하나 옳음을 증명할 수는 없는 것이 테스트 코드라는 것에 공감한다. 하지만, 그럼에도 불구하고 충분한 참을 위해서 안정성을 높이기 위해서 좀 더 다양한 케이스까지 테스트를 작성해야한다는 생각이 들었다. 엣지 케이스에 대해 소홀했던 점을 살짝 반성하게 되며 다양한 방식의 테스트를 충분히 고민해나가야겠다는 생각을 했다.

    객체 지향 프로그래밍

    의존성 역전은 소프트웨어 아키텍트 관점에서 심오한 의미를 갖는다. OO 언어가 다형성을 안전하고 편리하게 제공한다는 사실은 소스 코드의 의존성을 어디에서든 역전시킬 수 있다는 뜻이기도 하다.

    이러한 접근법을 사용한다면, 아키텍트는 시스템의 소스 코드 의존성 전부에 대해 방향을 결정할 수 있는 절대적인 권한을 갖는다.
    (49pg)

    이 책에서 전반적으로 장치독립성, 세부사항에 대해 독립성을 가지는 것에 대해 이야기를 한다. 그 근간은 의존성 역전이 자리잡고 있다. 정책을 세부구현과 독립함으로써, 세부구현에 휘둘리지 않게 만드는 것이다. 이 부분에서 정책과 관련된 내용이 나오진 않지만 책 전반을 읽으면서 정책을 코드를 통해 돌아가게 하는 것이 개발자라는 생각이 들었다. 따라서, 백엔드 엔지니어로써, 물론 프론트엔드 개발자와 소통하는 것도 중요하지만 기획자와 소통하며 그 내용을 구현하는 것이 중요할 것 같다는 생각이 들었다.

     

    SOLID 내용에 대한 설명도 해주는데 기존에 SOLID를 잘못 이해하고 있었다는 생각이 들었다. 세부사항을 작성하지 않겠으나 SOLID 원칙이 가지고 있는 것은 코드 수준이 아니라 아키텍처 수준의 내용이라는 생각이 들었다. 내가 책을 이해한 바로는 Java언어가 객체 지향을 지원하는 언어이지만 C언어에서 제공하는 캡슐화보다 사용하기 편리하도록 많은 부분을 풀어주었다는 내용이 나온다. C언어를 다루지는 못하여 온전하게 공감하긴 힘들지만, 객체 지향 언어라고 할지라도 사용하기 편리하기 위해 객체 지향 요소를 완화했다는 내용도 새로웠다.

    경계: 선 긋기

    소프트웨어 아키텍처는 선을 긋는 기술이며, 나는 이러한 선을 경계(boundary)라고 부른다. 경계는 소프트웨어 요소를 서로 분리하고, 경계 한편에 있는 요소가 반대편에 있는 요소를 알지 못하도록 막는다.
    (170pg)

    선을 긋는 기술이라고 표현했다는 것에 충격을 받았다. 각 요소들을 어떻게 나누고 관리할 것인지가 핵심이구나 하는 생각이 들었다. 아직 공부해보지 못했지만 DDD 관점에서 aggregate 를 기준으로 객체를 나눈다고 한다. 이런 것들 모두 선을 긋는 기준을 잡는 규칙을 소개하는 개발 방법론이라는 생각이 들었고, DDD 철학에 대해 더 공부해보고 싶어졌다.

    경계 해부학

    단일체와 배포형 컴포넌트 모두 스레드를 활용할 수 있다. 스레드는 아키텍처 경계도 아니며 배포 단위도 아니다. 이보다 스레드는 실행 계획과 순서를 체계화하는 방법에 가깝다. 모든 스레드가 단 하나의 컴포넌트에 포함될 수도 있고, 많은 컴포넌트에 걸쳐 분산될 수도 있다.
    (189pg)

    스레드가 가지는 역할에 대해 조금이나마 이해할 수 있게 해주는 문장이라고 생각했다. 나는 아직 스레드를 다루는 것에 상당히 미숙하다. 하지만 스레드를 다룰 때, 이것은 보다 실행계획과 순서에 측면에서 봐야하는 것이라는 생각이 들었다. 그러면서 운영체제를 공부하는 것은 서비스의 동작을 어떻게 이해할 것이가에 대해 도움이 된다는 생각이 들었다. 흠.. 운영체제 만들기 스터디 해보고 싶은데 할 수 있으련지 잘 모르겠다. 이 뿐만 아니라 장치 독립성을 이해하는데도 운영체제의 코드를 이해하는 것이 다형성을 가지는 구조를 이해하는데 도움이 많이 되겠구나 싶었다. 

     

    횡단 관심사

    아키텍처 경계가 서비스 사이에 있지 않다는 사실이다. 오히려 서비스를 관통하며, 서비스를 컴포넌트 단위로 분할한다. 횡단 관심사를 처리하려면, 서비스 내부는 의존성 규칙도 준수하는 컴포넌트 아키텍처로 설계해야 한다. 서비스들은 시스템의 아키텍처 경계를 정의하지 않는다. 아키텍처 경계를 정의하는 것은 서비스 내의 위치한 컴포넌트다.
    (259pg)

    프로젝트를 할 때, 문제가 되는건 제약조건과 다른 것들에 대한 필요성 때문이었다. 이것이 구분되는 것은 서비스 그 자체가 아니라 컴포넌트 단위라고 한다. 컴포넌트가 의미하는 바가 무엇인지는 아직도 잘 이해하지 못하겠다. 하지만, 소프트웨어에서 그 선의 경계는 컴포넌트고 문제 그룹 단위가 되는 것이 아닐까 생각해본다.

    테스트 경계

    (테스트를 고려하든 아니면 다른 이유든) 소프트웨어 설계의 첫 번째 규칙은 언제나 같다. 변동성이 있는 것에 의존하지 말라. GUI는 변동성이 크다. 따라서 시스템과 테스트를 설계할 때, GUI를 사용하지 않고 업무 규칙을 테스트할 수 있게 해야 한다.
    (263pg)

    변동성에 의존하지 말라! 항상 생각할 수 있어야 겠다.

    클린 임베디드 아키텍처

    "소프트웨어는 닳지 않지만, 펌웨어와 하드웨어는 낡아 가므로 결국 소프트웨어도 수정해야 한다." 
    소프트웨어는 닳지 않지만, 펌웨어와 하드웨어에 대한 의존성을 관리하지 않으면 안으로부터 파괴될 수 있다.
    (268pg)

    소프트웨어를 기계의 관점에서 생각해본 적이 없었다. 소프트웨어도 하드웨어, 펌웨어에 대한 의존성을 관리해야하고, 더더욱이 장치 의존성에 대한 의존성, 세부사항에 대한 의존성에 종속되지 말아야 하는 요소라는 생각이 들었다. 

    프레임워크는 세부사항이다

    프레임워크와 결혼하지 말라!
    (306pg)

    스프링 프레임워크가 생각났다. 가급적이면 프레임워크를 아키텍처 경계 너머에 두라고 한다. 종속되는 순간 분리되기 어렵기 때문이다. 제작근로를 하면서 어노테이선이었나 뭔가 import를 해서 쓸때, javax의 패키지의 내용이나, hibernate의 패키지 내용 중에 선택할 수 있을 경우 가능한 javax 패키지를 사용하는게 좋다고 했던 것이 생각났다. 그만큼 외부 기술은 세부사항이기 때문이 아닐까? 언제 바뀔수 있을지 모른다. 

    의존성 관리

    모든 의존성은 경계선을 한 방향으로만 가로지르는데, 항상 더 높은 수준의 정책을 포함하는 컴포넌트를 향한다.
    (314pg)

    레이어드 아키텍처가 생각이 났다. 항상 고수준의 것을 저수준의 세부사항의 의존하게 하고 그 의존성의 방향을 한 방향으로 하는 것이 상위 수준의 정책에 영향을 미치지 않을 수 있다. 방향은 한 방향으로 가자!

    맺는 글

    설계와 관련된 모든 결정은 미래에 발생할 변경에 문을 열어 둘 수 있어야 한다. 포켓볼을 치는 것과 마찬가지로, 샷을 칠 때 그저 공을 구멍에 넣는데 그쳐서는 안 된다. 공들이 다음 샷을 치기 쉬운 위치에 멈춰 서게 만들어야 한다.
    (388pg)

    비유를 이런 방식으로 한 것이 재밌었고 공감이 되었다. 운동하는 것을 좋아하는데, 게임을 할 때 다음 수를 어떻게 해야 좋을지 고민해야 게임에서 더 쉽게 이길 수 있는 것과 같은 것 아닐까?ㅎㅎㅎ

     

    이해하기 어려워서 궁금한 부분

    321~330 페이지의 세부사항 파트를 읽다보면 패키지 의존성 그래프 부분이 있다. 여기서 평소에 Service까지는 인터페이스로 작성하지 않았어서 ServiceImpl를 구현하는 방식 부분이 좀 어떤 경우일까 좀 궁금했다. 그리고 여러가지 패키지 구조가 나오는데 web, domain, database로 나눠져서 service가 domain에 들어가게 되는 구조는 어떤 구조일까 고민되기도 했다. 인프로와 도메인 이렇게만 나눌 경우 패키지 구조를 이렇게 가져간 것일까?

     

    의존성 방향에서 몇 유스케이스는 Controller가 Service를 지나치고 도메인을 의존하는 경우가 있는데 이는 CQRS 패턴을 지키려고 시도하는 경우라고 한다. CQRS는 들어보기만 하고 공부를 따로 해본 적은 없어서 어떤 방식으로 구현되는지 좀 궁금해졌다. 

    클린 아키텍처 330pg

    다양한 패키지 구조가 나오는데 어떤 경우에 각각의 패키지 구조를 사용하는 건지 궁금했다. 미션과 프로젝트를 하면서 흔히 보았던 패키지 구조와 좀 달라서 새로웠다. 그 동안에 잘 몰라서 관습적으로 기존에 구성되어 있는 패키지 구조를 따라 사용했는데 어떤 의도를 가지고 패키지를 나누는 것이 좋은지 생각할 필요가 있다는 생각을 했다.

    마무리

    일단 책이 너무 재밌었고, 평소에 포스트잇을 잘 안 붙이는데 이 책은 포스트잇을 덕지덕지 붙여가며 읽을 정도로 흥미로운 책이었다. 좋은 책들을 많이 읽고 싶다는 생각이 들게 해준 책이었다. 인상 깊었던 내용 포스트잇 위주로 정리하고 나의 생각을 작성해 보았다. 아마 개발자로써 실무를 경험하고 나고 이 책을 다시 본다면 또 다른 시각으로 책을 이해할 수 있을 것이라는 생각이 든다. 좀 더 깊은 고민을 하고 판단 기준을 잡는데 책에서 얻는 인사이트가 많이 필요할 것 같다는 생각이 든다.

     

    무튼 안 읽어봤다면 읽어보길 매우 추천하는 책이다.

     

    댓글

Designed by Tistory.