이번 포스팅에서는 클린 코드에 대한 주관적인 견해를 나누고자 합니다. 먼저 말씀드리고 싶은 것은 이 글이 절대적인 진리를 담고 있는 것이 아닌, 개인적인 경험과 생각을 바탕으로 한 주관적인 견해임을 미리 밝힙니다.
클린 코드에 대한 정의는 사람마다 조금씩 다를 수 있습니다. 코드의 가독성, 유지보수성, 효율성 등 다양한 측면에서 접근할 수 있기 때문입니다.
포스팅 내에 링크는 관련 설명과 영상으로 참고하면 좋을 것 같습니다.
코딩은 계속될 것인가 ?
“코드의 종말이 코앞에 닥쳤다고 주장하는 사람이 없지 않다. <중략>
앞으로 코드가 사라질 가망은 전혀 없다!
왜? 코드는 요구 사항을 상세히 표현하는 수단이니까!”
- 로버트 C. 마틴, <클린 코드>"
저자 의도
선동적이고 극단적인 표현을 걷어내고 내용을 봐야합니다.
좋은 코드를 작성하고 싶은에 어떻게 해야 하나요 ?
-> 객체지향을 공부하세요.
이러한 설명에 대해서 어떻게 설명하시나요 ?
객체 지향의 패러다임은 다양한 사람이 다양한 관점으로 발전시킨 개념으로 하나로 통합이 가능할까? 라는 의문이 생길 수 있습니다.
다양한 관점에서 보는 객체지향은 아래와 같습니다.
설명 | |
---|---|
명사(데이터) 중심 | - 데이터를 중심으로 관련 절차(함수)를 캡슐화 - OOAD와 자료구조로서 객체의 관점 - -er 로 끝나는 이름 금기 |
동사(기능) 중심 | - 객체를 작은 컴퓨터(입력과 출력)로 보는 관점 - 메시징과 객체 간 협력 강조 - 상태는 지역적으로 은닉 - Tell, Don`t Ask |
객체 중심 | - 프로그램의 기본 구조로서 객체 - 객체의 캡슐화와 정보 은닉 측면 강조 - 대부분의 주요 OOP 프로그래밍 언어 |
객체 보조 | - 자료 구조 또는 추상 자료형 관점 객체 활용 (CLU, CLOS, OCaml) - 객체의 다형성 측면 강조 - 토니 호어의 레코드 처리 |
"분별 있는 프로그래머는 모든 것이 객체라는 생각이 미신임을 잘 안다" ->
엉클밥
https://www.youtube.com/watch?v=eXCx2hW_xNI&t=1633s
OOP와 DOP의 기술은 서로 상충되지 않고 서로 다른 입도와 상황에 맞는 서로 다른 도구이다.
필요에 따라 자유롭게 혼합하여 사용할 수 있다.
- 브라이언 게츠
"처음부터 클린 코드를 작성하면 리팩터링이 필요 없다."
<클린 코드>의 첫장에는 아래와 같은 설명이 있습니다.
보이스카우트 규칙
즉, 내가 커밋할 때 이전보다 깨끗하게 만들어서 커밋하라는 말인데, 이게 리팩토링이다. 클린 코드의 핵심 중 하나가 리팩토링인데
클린 코드를 작성하면 리팩터링이 필요 없다.
이 말은 어불성설 이라고 볼 수 있다고 생각합니다.
마틴 파울러가 리팩터링이란 책에 정의한 사전적 정의
소프트웨어의 겉보기 동작은 그대로 유지한 채, 코드를 이해하고 수정하기 쉽도록 **내부 구조를 변경**하는 기법
"계획을 세워서 리팩토링 작업을 진행하는 경우도 있지만,
나는 리팩토링을 언제 어디서나 코드를 정리해야 할 때 누구든 할 수 있는 기회주의 활동으로 장려하고 싶다."
마틴 파울러
관련 설명
https://martinfowler.com/bliki/OpportunisticRefactoring.html
다들 리팩터링이 좋다는건 어느정도 알고 계실거라고 생각합니다.
그런데 리팩터링을 꾸준히 해오시는 분은 없다고 생각합니다.
저 또한 그렇구요,,
리팩터링은 코드 변경을 동반하는 작업이기 때문에, 코드를 변경함으로써 예상치 못한 결과가 발생하지 않을까 하는 불안과 시간 부족의 핑계로 많은 사람들이 꾸준한 리팩터링을 소홀히 하는 경향이 있습니다.
<클린 코드> 내용 中
“실제 코드를 점검하는 자동화된 단위 테스트 슈트는 설계와 아키텍처를 최대한
깨끗하게 보존하는 열쇠다. 테스트는 유연성, 유지보수성, 재사용성을 제공한다.
테스트 케이스가 있으면 변경이 쉬워지기 때문이다.”
테스트 케이스가 있으면 변경이 쉬워지고 이것은 일종의 안정망이라고 볼 수 있죠.
“이 책(디자인 패턴)은 설계를 독립된 단계로 바라보는 성향을 어렴풋이띈다. 이 책은 확실히 리팩터링을 설계의 일종으로 보는 것에 동의하지 않는다. TDD에서는 설계를 디자인 패턴과는 조금 다른 관점으로 본다.”
켄트 벡, 테스트 주도 개발
테스트를 먼저 작성한 뒤, 발생하는 fail을 해결하기 위한 최소한의 코드를 작성한다. 즉, 일단 동작하게 만든 뒤 리팩토링을 거친다.
이 구조를 반복한다.
마틴 파울러의 "리팩터링"
에서는 기존의 코드를 변경하지 않고도 코드를 이해하고 수정할 수 있는 설계를 갖추는 것이 중요하다고 강조하며, 리팩터링을 통해 코드를 개선하는 방식을 제시하고 있습니다.
반면에, 켄트 벡의 테스트 주도 개발(TDD)
에서는 테스트를 먼저 작성하고 해당 테스트를 통과시키기 위한 최소한의 코드를 작성한 후에 리팩터링을 진행하는 방식을 강조합니다. TDD에서는 테스트 코드를 통해 안정성을 유지하면서 코드를 개발하고, 그 후에 리팩터링을 통해 코드를 개선하는 것이 접근법입니다.
아래 과정은 좋은 설계의 창발입니다.
"창발"은 일반적으로 의도치 않게 떠오르거나 예상하지 못한 결과가 나타난다는 의미로 볼 수 있습니다.
켄트 벡의 단순한 설계 규칙
켄트백이 말한 4가지 단계를 계속해서 리팩터링 하다보면 어느순간 나도 모르게 의도하지 않았는데 좋은 설계가 이루어진다고 볼 수 있습니다.
아키텍처는 시스템에 오랫동안 큰 영향을 미치므로 초기에 심사숙고해서 결정해야한다..?
“그때 아키텍트들이 왔다. 그들은 XP가 프로그래밍에는 맞을지 몰라도, 아키텍처를 프로젝트 초기의 어느 단계에서 설계할 수 있도록 해준다면 모든 일이 훨씬 매끄럽게 진행될 거라고 설명했다. 사람들은 이에 대해, 흐름을 옹호해야 하며, 아키텍트 역시 흐름 원칙에 따라서 처음에는 아키텍처를 시작하기 충분할 정도로만 만들고 일을 진행하면서 꾸준히 다듬어가야 한다는 주장을 아키텍트들에게 퍼부었다. 결국 그들은 마지못해그렇게 하겠다고 동의했지만, 그래도 아키텍처 단계가 따로 있는 만큼 좋지는 않을 것이라고 말했다.”
켄트 벡, 익스트림 프로그래밍
즉, 아키텍트들이 프로젝트 초기에 아키텍처를 설계하고자 했으나, 개발자들은 초기에 아키텍처를 수립하는 것에 동의하기 어려워 했다는 내용을 담고 있습니다.
이는 초기에 전체 시스템을 완벽히 설계하는 대신, 초기에는 작은 규모의 시스템을 빠르게 작성하고, 나중에 그 시스템을 필요에 따라 확장하고 개선하는 방식을 지지하는 익스트림 프로그래밍(XP)의 접근법입니다.
XP 팀은 나누고 정복하지 않고, 정복하고 나누고 또 정복한다. 처음에는 소규모 팀이 소규모 시스템을 작성한다. 그런 다음 자연스러운 분할선을 찾아 시스템을 비교적 독립적인 부분으로 나누어 확장한다.”
켄트 벡, 익스트림 프로그래밍
이 원칙은 문제를 처음부터 나누어 해결하는 대신, 문제를 이해하고 나아가면서 발전된 이해를 기반으로 계속해서 접근하고 개선해 나가는 것을 강조합니다.
특히, 소규모로 시작하되, 계속해서 이해를 쌓아가며 나아가면서 아키텍처도 나누고 설계도 개선해 나가는 접근법입니다.
이는 초기에는 간단한 솔루션으로 빠르게 시작하고, 시스템의 복잡성이 증가함에 따라 필요에 맞게 나누고 정복하며 발전시켜 나가는 방식을 의미합니다.
소프트웨어 시스템은 물리적인 시스템과 구별되며, 적절한 관심사에 따라 모듈을 나누고 관리함으로써 소프트웨어 아키텍처도 점진적으로 발전할 수 있습니다.“소프트웨어 시스템은 물리적인 시스템과 다르다. 관심사를 적절히 분리해 관리한다면 소프트웨어 아키텍처는 점진적으로 발전할 수 있다.”
펙토리, DI, AOP...
모듈을 잘 나누어 분리함으로써 아키텍처를 개선하는 일 또한 수월해집니다. 스프링 프레임워크가 널리 사용되고 인기를 얻는 이유 중 하나는 소프트웨어가 유연하며, 관심사에 따라 모듈화되어 있어서 추후 아키텍처를 개선하고자 할 때 용이하게 개선할 수 있도록 만들어졌기 때문입니다.
삼각형의 의미를 왜 이해하고 있어야 할까 ?
에 대한 질문은 왜 필요할까? 로 받아들이면 좋을 것 같습니다.
소프트웨어는 지속적으로 변하며, 출시 이후에도 시장 상황과 요구사항이 변합니다. 서비스 규모가 증가하거나 환경이 변할 때, 스케일 아웃이나 클라우드 이전과 같은 변화가 필요할 수 있습니다. 이 끊임없는 변화 속에서 소프트웨어가 살아남기 위해서는 변화에 빠르게 적응할 수 있어야 합니다. 스프링을 사용함으로써 아키텍처를 개선하고, 이러한 변화에 적응하기 좋은 소프트웨어를 만들 수 있습니다.
진화적 아키텍처
의 용어는 예전부터 떠돌고 다니는 용어로 이 책이 90년도에 한번 나오고 2판이 나왔으며, 최근에 번역되었습니다.
이 책은 아키텍처는 진화해야한다고 설명하고 있으며, 비교적 단순한 내용을 복잡하게 써서 어려울 수 있지만 앞부분 적합성 함수 부분을 제외하면 읽는데 큰 부담이 없다고 합니다.
결론은 잘 모듈화된 시스템이 있고, 테스트가 있으며, 그것이 잘 돌아가게 만드는 CICD 파이프 라인이 있다면 아키텍처도 계속해서 진화할 수 있다고 합니다.
공산품
vs 생물
어떻게 생각하시나요 ? 저는 아래 의견에 동의합니다.
소프트웨어는 키우는 것으로 정해진 놓은 것을 한번 만들고, MVP,결과물을 내고 시장에 쓰면서 계속해서 피드백을 받아가며 개선해 나가다가 상황에 맞춰서 런타임을 바꾼다던가, 요구사항을 바꾸며 상황에 따라 바뀌면서 생물이 환경에 적응해서 진화하듯이 계속해서 키워나간다.
프로그래머는 주로 사용자와 기계 사이의 공간을 다루는 역할을 합니다. 요구사항을 받아 기계가 이해하는 코드로 변환하고, 사용자의 필요에 맞게 컴퓨터가 실행하도록 만드는 것이 프로그래머의 역할입니다.
그러나 또 다른 관점이 존재합니다. 구글 소프트웨어 엔지니어링
책에서는 소프트웨어가 시간에 따라 계속해서 변화해야 한다는 개념을 강조합니다. 이 전통적인 관점은 한 순간의 업무에 초점을 맞추는 반면, 소프트웨어는 시간을 통해 성장하고 진화하며 살아가야 한다는 측면을 강조하고 있습니다.
클린 코드에 대한 관점을 추가
하면, 소프트웨어 엔지니어링에서는 클린 코드가 소비자나 컴퓨터뿐만 아니라 나와 같이 협업하는 동료를 위해 작성되어야 한다는 중요한 개념이 있습니다. 클린 코드의 내용과 테스트 코드는 처음에는 익숙하지 않을 수 있지만, 이를 통해 나만 아니라 동료들과의 협업을 원할하게 만들 수 있습니다.