Skip to content

직관을 따라야 읽기 좋고, 읽기 좋아야 고치기 좋다.

HJ, Ph.D. / Software Architect
(js.seth.h@gmail.com)
초안: 2023년 01월 / 개정: 2025년 12월

Abstract

  • 가독성과 유지보수성의 상관 관계는 많이 언급된다.
  • 그런데 가독성을 명확히 정리하는 내용은 별로 없다.
  • 그저 직관적인 코드나 읽기 쉬운 코드라고 표현될 뿐이다.
  • 대체 가독성이란 무엇인가? 내용을 쉽게 이해한다는 것은 무엇인가?
  • 커뮤니케이션: 발신자(Sender), 메시지(Message), 채널(Channel), 수신자(Receiver), 효과(Effect)
  • 수용 이론(Reception Theory)
  • 직관이란 무엇인가?
  • 전산학은 개발자라는 집단의 공유 리터러시
  • 인지 부하 이론
  • 기초에 충실하면 수정 포인트를 정하기 좋다.
  • 집단적 직관에 충실해라. 그러기 위해서 많은 것을 보고 배워라.

가독성과 유지보수성

가독성과 유지보수성은 소프트웨어 논의에서 자주 함께 언급되는 개념이다. 일반적으로는 “읽기 쉬운 코드는 고치기 쉽다”라는 문장으로 요약되지만, 이 명제는 이유에 대한 설명을 충분히 제공하지 않는다. 그 메커니즘에 대한 설명은 더욱 부족하다.

유지보수란 본질적으로 연속성을 가진 변경이다. 변경은 기존 코드의 구조와 의도를 이해하는 행위를 전제로 한다. 이 점에서 가독성은 미적 속성이나, 부차적인 품질이 아니라, 유지보수가 가능해지기 위한 전제 조건이다.

읽을 수 없는 코드는 완전히 다른 코드로 대체는 가능할지언정, 이해할 수 없기에 부분 수정이 불가능하다. 때문에 유지보수는 언제나 개발자의 해석 능력과 작성 능력이 함께 요구된다. 그러나, 대부분의 평범한 한국 개발자가 산스크리트어를 읽을 수 없듯이, 해석 능력이란 기존에 작성된 텍스트와 결부된 요소이다.

가독성의 작동원리는?

가독성 – 쉽게 이해한다, 직관적으로 파악된다는 것은 구체적으로 어떤 과정인가? 우리는 '쉽게 이해한다'에서 '쉽게'의 의미를 '시간이 적게 걸렸다'와 '정확하게 파악했다'로 대충 갈음하는 경향이 있다. 그리고 그 원인을 '직관적 코드'로 자주 얼버무린다.
물론 타당한 관찰이긴 하다. 그러나 그 속에는 너무 많은 것이 생략되어 있다.

우선 "이해한다"는 표현부터 파악해보자. 상당히 추상적인 표현이지만, 실제로는 비교적 명확한 인지 과정으로 분해할 수 있다. 개발자가 코드를 읽을 때 수행하는 과정은 대략 다음과 같다. 첫째, 구조를 파악한다. 코드의 시작과 끝, 흐름의 방향, 책임의 경계를 인식한다. 둘째, 의미를 해석한다. 변수명, 함수명, 타입, 주석 등을 통해 작성자의 의도를 복원한다. 셋째, 결과를 예측한다. 해당 코드가 어떤 동작을 하며, 어떤 인과 관계가 성립하는지 파악한다.

가독성은 단순히 '이해'를 말하지 않는다. 이해하기 '쉬운' 성질을 말한다. 그럼 쉽고 어렵고의 성질, 즉 이해의 난이도에 관여하는 요소가 무엇인지 알아봐야 한다.

커뮤니케이션의 구성

글은 전통적으로 커뮤니케이션의 한 분류이다. 그리고 코드는 인간이 컴퓨터에게 지시한 아주 상세하고 구체적인 지시글이다. 이 글은 컴퓨터가 읽어서 실행하며, 동료나 미래의 내가 읽어서 수정한다. 그러니, 우리는 '쉬운' 성질이 무엇인지 알기 위해서 커뮤니케이션에 대한 인류의 지식을 차용할 수 있다.

커뮤니케이션 이론에는 말하는 발신자, 메시지, 채널, 수신자, 효과 등이 언급된다.

  • 발신자(Sender): 정보를 전달하려는 사람 또는 집단
  • 메시지(Message): 전달하고자 하는 내용이나 정보
  • 채널(Channel): 메시지가 전달되는 매체나 경로(예: 말, 편지, 코드, 라디오, 방송 등 )
  • 수신자(Receiver): 메시지를 받아들이는 사람 또는 집단
  • 효과(Effect): 메시지 전달 후 수신자에게 나타나는 변화나 반응

여기서 우리는 커뮤니케이션 - 즉 내용의 전달이란, 화자와 청자가 상호작용이며, 같은 발신자, 메시지, 채널이라도 수신자가 다르면 효과도 달라진다는 것을 알 수 있다. 무슨 소리가 이해가 안 된다면, 청자를 개발자와 컴퓨터로 놓으면 간단해 보인다. 동일한 코드를 컴퓨터가 수신할 때는 명령대로 처리를 하겠지만, 개발자가 수신할 때는 전혀 그렇지 않다. 우리는 다른 목적으로 코드를 본다.

이는 영국의 문화이론가이자 미디어 학자인 Stuart Hall에 의해 수용 이론(Reception Theory)으로 발전한다.

수용 이론

수용 이론은 텍스트의 의미가 작성 시점에 고정되는 것이 아니라, 독자의 해석 과정에서 의미가 완성된다고 설명한다.

Stuart Hall은 특정 미디어 메시지가 단순히 송신자(Sender)의 의도 그대로 전달되는 것이 아니라, 수신자(Receiver)가 자신의 문화적 맥락과 배경에 따라 해석한다고 보았다.

소스 코드도 이 이론에서 예외가 될 수 없다. 같은 코드라도 독자의 경험, 지식, 맥락에 따라 이해 방식은 달라진다. 따라서 중요한 것은 작성자의 의도가 무엇이었는가가 아니라, 수신자가 얼마나 일관되게 작성자와 동일한 의미로 해석할 수 있는가이다. 즉 '가독성이 좋다 = 이해하기 쉽다'는 표현의 개성이나 고유성, 문제의 복잡성과 같은 요건이 아니라 해석의 안정성 / 수렴성에 관한 문제이다.

실무 환경에서 소스 코드는 프로그래밍에 대한 전문지식이 없는 일반인에 의해 읽히는 물건이 아니다. 그렇다고 특정 개인만을 대상으로 하지도 않는다. 소스코드는 개발자 집단에 의해 읽히고 수정된다. 그러니, 해석의 안정성 / 수렴성의 기준을 전문 지식을 가진 개발자로 한정하도록 하자.

직관은 감각인가? 지식인가?

그럼 개발자라는 집단을 기준으로 할 때, 수용의 난이도는 어떻게 결정되는가?

직관은 종종 감각적 판단이나 개인적 능력으로 오해되지만, 실제로는 축적된 지식과 경험이 압축된 결과이다.
직관이 뛰어난 것을 '유전적 요소'로 보는 경우가 많은데, 엄연히 직관은 지식의 축적과 경험을 통해서 훈련 가능한 특성이다. (물론 개인별 습득의 유불리는 유전이 맞겠지만...) 대놓고 말해 중간 과정을 생략한, 대체로 옳은 편견/편향이 그 정체이다.

그래서 직관은 주관적 감각이 아니라 반복적으로 강화된 지식이며, 우연적 감정이 아니라 수많은 사례에서 형성된 패턴 인식의 결과이다.

그래서 개발자라는 전산학 분야 전문 지식을 동질성으로 가진 하나의 집단을 상정할 때, 직관은 공유가 가능하다.
만약, 직관이 온전히 개인적 감각이라면 코드를 직관적으로 작성하는 것은 가능해도, 집단이 직관적 코드임을 공통적으로 평가하는 것은 불가능하다. 우리가 특정 코드가 직관적인지 아닌지 논의할 수 있다는 사실 자체가, 우리가 직관을 이미 공유하고 있으며, 그것이 감각이 아니라 지식 - 정확하게는 사회화된 암묵지에 기반한다는 증거이다.

사회화된 암묵지의 정확한 개념은 일본의 경영학자 노나카 이쿠지로(Ikujiro Nonaka)가 체계화한 지식창조이론(Knowledge-Creation Theory)을 참고해라.

전산학 == 개발자 리터러시(Developer Literacy)

우리가 공유하는 직관의 원천은 결국 대학교육을 통해서 정립된 전산학 지식이다.

개발자 집단의 리터러시는 전산학이라는 공통 지식 위에서 형성된다. 자료구조, 알고리즘, 추상화, 모듈화, 상태와 흐름에 대한 이해는 개발자 집단의 공용 언어이다. 가독성이 높은 코드는 이러한 공용 언어를 적극적으로 활용한다. 반대로 전산학적 맥락을 무시한 독자적 구조는 이해 비용을 급격히 증가시킨다. 이 점에서 가독성이란 친절함의 문제가 아니라, 전산학적 지식 수준 & 개발 문화에 대한 적응에 대한 문제로 변환된다.

실제로 전산학 개념은 교과서 속에서 추상적으로 존재하지 않는다. 성공한 프로젝트에서는 적절하게 선택된 전산학 개념이 구조적 선택으로 고정되어 있으며, 이 선택이 곧 가독성과 이해 비용을 결정한다. 다음의 사례들은 대표적인 예시다.

  1. Git 로그 - DAG(방향 비순환 그래프)
    Git에서 커밋은 단순한 로그가 아니라, 방향 비순환 그래프(DAG)를 이루는 불변 객체이다. 각 커밋은 부모를 참조하며, 브랜치와 태그는 이 그래프의 특정 노드를 가리키는 포인터에 불과하다. 머지 역시 새로운 커밋을 생성하여 그래프를 확장하는 행위로 모델링된다.
    이 선택 덕분에 “히스토리 관리”라는 복잡한 문제는 그래프 탐색과 포인터 이동이라는 전산학적 문제로 환원된다. 만약 Git이 변경 이력을 단순한 순차 로그나 임의의 스크립트 집합으로 관리했다면, 현재와 같은 이해 가능성은 확보되기 어려웠을 것이다.

  2. TCP 프로토콜의 상태 - 유한 상태 기계(State Machine)
    TCP 연결은 LISTEN, SYN_SENT, ESTABLISHED, FIN_WAIT 등 명확하게 정의된 상태들과 그 사이의 전이로 구성된다. 각 상태에서 가능한 동작과 불가능한 동작은 명시적으로 제한된다.
    이 구조는 네트워크 통신의 단계라는 복잡하고 오류 가능성이 높은 문제를 “상태 전이의 집합”으로 단순화한다. 개발자는 모든 경우의 수를 머릿속에서 시뮬레이션할 필요 없이, 현재 상태와 다음 상태만을 고려하면 된다. 문제의 복잡성은 제거되지 않았지만, 상태 모델을 통해 통제 가능한 형태로 변환된 것이다.

  3. RESTful API - Resource Identifier
    REST는 시스템의 동작을 나열하는 대신, 자원(Resource)을 중심으로 인터페이스를 정의한다. /users/{id}와 같은 URI는 해당 자원이 무엇이며, 어느 범위까지 책임을 가지는지를 암묵적으로 규정한다. GET, POST, PUT, DELETE와 같은 제한된 동사는 자원에 대한 행위의 종류를 표준화한다.
    이 모델에서는 API의 가독성이 문서의 충실함보다 경계 설정의 명확성에 의해 결정된다. 리소스가 잘 정의된 시스템에서는 새로운 엔드포인트를 보더라도, 그 역할과 사용 방식이 큰 설명 없이도 예측 가능하다.

리터러시(Literacy) - 문해력?

리터러시(Literacy)는 전통적으로 문자를 읽고 쓰는 능력을 의미했다. (= 문해력을 의미했다.)
그러나, 현대에 와서는 특정한 지식이나 기술을 적용하여 정보를 이해하고 활용하는 더 폭넓은 의미로 확장된 개념이다. 이는 단순히 언어적 능력을 넘어, 다양한 맥락에서 비판적 사고와 창의적 문제 해결 능력을 포함한다. 예컨대, 미디어 리터러시는 미디어 콘텐츠를 분석하고 해석하며 생산할 수 있는 능력을 요구하고, 정보 리터러시는 신뢰할 수 있는 정보를 평가하고 이를 효과적으로 사용하는 역량에 초점을 둔다.

따라서 리터러시는 특정한 주제, 기술, 혹은 상황에서의 이해와 소통·적응·활용 능력을 포괄하는 개념이다.

인지 부하 이론

그러나 집단이 직관을 공유할 수 있다는 점이 가독성의 차이 - 즉, 개인의 표현능력과 수용능력 차이를 설명하지 않는다.

인지 부하 이론은 인간의 작업 기억이 매우 제한적이라는 전제에서 출발한다. 한 번에 처리할 수 있는 정보의 양에는 한계가 있으며, 이 한계를 초과하면 이해는 급격히 저하된다. 여기서 주요하게 볼 부분이 2개가 있는데, 내재적 인지 부하 (Intrinsic Cognitive Load), 외재적 인지 부하 (Extraneous Cognitive Load)이다.

"인지 부하 이론(Cognitive Load Theory)"은 호주의 교육 심리학자 존 스웰러(John Sweller)가 1988년 그의 논문에서 제시했다.

본디 이 이론은 교육 - 즉 학습의 관점에서 제시된 것이나, 개발자가 과거 작성한 코드 또는 타인이 작성한 코드를 보는 것도 일종의 학습에 해당하며, 이를 차용할 수 있다. 내재적 인지 부하는 코드의 목표 기능이 가진 고유의 복잡성과 관련된 부하로 볼 수 있으며, 외재적 인지 부하는 코드의 표현 방식으로 인해 불필요하게 증가하는 부하로 정의할 수 있다.

이와 같은 지적 능력의 부하는 곧 이해의 정확도와 시간과 연결된다. 즉 가독성의 난이도를 결정하는 주요 원인으로 발신자 --코드--> 수신자 사이에서 발생하는 인지 부하의 총량으로 이해할 수 있다.

그리고 이러한 인지 부하의 총량, 즉 가독성은 개선이 가능하다. 목표 기능이 고유성, 독자성을 지닌다면 내재적 인지 부하를 경감할 방법이 다소 제한되겠지만, 상용 제품에서 로그인과 같은 다수의 기능은 고유성이 매우 낮다. 그리고 외재적 인지 부하에서 주로 언급되는 표현 방식의 경우, 프로그래밍 언어의 예약어가 제한된 점과 전산학적 개념의 잘 알려진 표현을 차용할 수 있다는 점을 감안하면 상당히 경감 가능하다.

이처럼 개인적 능력의 편차로, 메타포의 적절성, 의사소통의 효율, 의사 결정 정확성 등이 차이가 난다.
때문에, 경력자로만 구성된 팀이 초보자까지 포함된 팀보다 더 적은 수로도 더 많은 성과를 내는 것이 설명 가능하며, 각 문제 상황별로 최적의 전산학 개념을 가져와서 응용 가능한 중급~고급 개발자와 그렇지 못한 초급~중급 개발자 사이에 큰 차이를 설명한다.

직관과 관습

대게 직관과 관습은 무관하거나 반대인 것으로 여겨진다.
그러나 직관과 관습은 중간 과정을 생략한, 대체로 옳은 편견/편향이라는 점에서 아주 비슷하다. 다만 직관은 대체로 개인이 지금 상황에 맞게 도출한 암묵지이고, 관습은 사회가 평균적인 상황에 맞게 도출한 암묵지라는 차이점이 있다.

관습은 집단적 경험이 시간에 따라 응축된 결과이다. 반복적으로 사용되며 살아남은 구조와 표현은 대체로 괜찮은 결과를 기대할 수 있기 때문에 관습이 되었다. 그리고 일단 관습이 되면 의사소통이 유리해지기 때문에 빈번히 사용되고, 결과적으로 더 많은 경험이 응축되면서 점점 더 강화된다. 그래서 관습이 해결하는 문제는 평균에 수렴한 문제이며, 평균 수렴한 해법이다. 때문에 각기 다른 조직이 겪는 문제의 고유 개성은 관습적 해법으로 풀 수 없는 경우가 발생한다.

반면, 직관은 오롯이 개인의 안에서 작용한다. 비슷한 학습자료와 비슷한 경험, 토론 등을 통해 직관을 공유하는 것은 가능하지만, 직관의 발휘 자체는 오롯이 개인의 몫이다. 또한 직관의 대상 역시 개인의 관점에서 바라보며, 개별 문제의 특이성에 따른 대응을 할 수 있다.

이런 차이점 때문에 직관과 관습의 관계는 개인적 성취와 연관된다.
저년차 개발자들은 일반적으로 관습을 넘어서기 어렵다. 그러나 개인의 경험과 통찰이 관습의 바탕이 되는 가상의 평균선을 넘어서게 되면, 반대로 관습이 직관을 따라오기 힘들다.

그러나 관습은 집단 지성의 결과라는 측면 때문에 대체로 평균 상위의 해법을 제시하며, 의사소통의 효율성이라는 부가적인 이점을 가져온다. 때문에 조직원 간 리터러시를 높은 수준으로 동화하기 힘든 복잡한 프로젝트에서는 관습적인 통용을 가급적 유지하는 것이 유리할 수 있다.

다만 위 결론은 관습의 단순 모방에 적용되기는 어렵다. 애초에 관습 자체가 암묵지라서 단순 모방이 제대로 되지 않기 때문이다.

유지보수와 리터러시

가독성은 추상적이거나 모호한 개념으로 받아들여지지만, 상세히 분석하면 생각보다 그렇지 않다. 집단적 공유 리터러시에 충실하면 인지부하가 줄어들며, 개인의 능력치에 따라 높은 수준의 직관을 발휘할 수 있다. 즉 빠르고 정확하게 파악하여 적절한 수정점을 찾기 용이하다.

개인의 능력치에 따른 편차는 개별 상황에서는 실질적으로 상수이므로, 관습적 형태에 충실한 - 즉 직관을 발휘하기 좋은 설계와 소스 코드를 작성하고, 적절한 자격을 갖춘 인력을 투입한다면 유지보수의 비용을 낮출 수 있다.

혹자는 유지보수를 과거의 나와 현재의 나 사이의 다툼이라고 표현한다. 이는 달리 말해, 과거와 현재의 나가 일정한 리터러시를 공유하고 있지 않았다는 점을 보여준다. 가령 어떤 로직을 처리하기 위해 유한 상태 기계(Finite State Machine, FSM)를 차용하기로 하였다면, 기준이 되는 표준적 모형이 있으므로 의사결정 과정에서 검토되는 전제 조건과 논리 전개, 그리고 결론이 유사하게 나온다. 반면, 그 로직의 복잡성을 제어하기 위해 차용한 전산학적 모델이 없다면, 그때 그때의 선호에 따라 다른 결론이 나고, 충돌이 생기기 쉽다.

간단히 말해, "왜 이렇게 했지?"라는 의문 자체가 과거와 현재 사이 또는 전임자와 후임자 사이에 리터러시가 공유되지 않기에 발생하는 일이며, 역으로 리터러시가 공유된다면 피할 수 있는 상황이라는 점이다.

결론

가독성은 감각적 미덕이 아니라 '의사소통, 직관, 집단 지식, 인지, 사회화, 관습'이 교차하는 실천적 개념이다.
모호하거나 추상적인 표현이 아니라, 그 작용 기전을 설명할 수 있는 개념이다.

가독성 관한 지침 - '읽는 것을 전제로 작성하라'는 지침은 유효한 지침이나, 생략이 너무 많다.

읽기 좋은 코드는 이해하기 쉬운 코드이자, 다른 사람이 고치기 쉬운 코드이다.
그 전제는 집단적 직관과 전산학적 지식 - 즉 실력 좋은 개발자가 공유하는 리터러시에 충실한 구조이다.

직관을 따르라는 말은 느낌이 이끄는 대로 작성하라는 뜻이 아니다. 더 많은 사례를 보고, 더 많은 지식을 내면화하라는 요구이다.
관습을 따르라는 말은 단순 모방하라는 뜻이 아니다. 사회화된 집단적 암묵지를 개인의 내면으로 수용하라는 요구이다.

전공서를 냄비 받침으로 쓰려거든, 적어도 후배들에게 설명해 줄 수 있을 정도로는 읽어 보았길 바란다.

SeeAlso

Author

HJ, Ph.D. / Software Architect
(js.seth.h@gmail.com)
https://js-seth-h.github.io/website/Biography/

Over 20 years in software development, focusing on design reasoning and system structure - as foundations for long-term productivity and structural clarity.

Researched semantic web and meta-browser architecture in graduate studies,
with an emphasis on structural separation between data and presentation.

Ph.D. in Software, Korea University
M.S. in Computer Science Education, Korea University
B.S. in Computer Science Education, Korea University