깨끗한 코드란?

추천사와 좋고 나쁜 코드의 구분

책너두 5기 2일차

로버트 C.마틴의 클린코드

내용 정리

추천사 (James O. Coplien)

덴마크의 속담에는 ‘사소한 곳에서 발휘하는 정직은 사소하지않다.’ 라는 말이 있다. 이 책을 읽을 때 가져야 하는 자세를 말해준다. 소프트웨어 개발에서 아키텍쳐가 중요하다는 것은 누구나 동의한다. 책임 있는 전문가라면 프로젝트를 시작할 때 생각하고 계획할 시간을 확보해야 한다. 세세함의 주의를 기울이는 태도는 당연하지만 두 가지 이유로 중요하다.

  1. 큰 실무에서 실력을 쌓고 신뢰를 얻으려는 전문가는 먼저 작은 실무부터 실력을 쌓고 신뢰를 얻어야 하기 때문
  2. 꼭 맞게 닫히지 않는 문이나 비뚤어진 바닥 타일이나 지저분한 책상 등 아주 사소한 것들이 전체의 매력을 깎아먹기 때문

대다수의 활동은 제조가 아닌 유지보수와 관련되어 있다. 과거 일본에서 나타난 TPM(Total Productive Management)이라는 품질관리론이 있다. 여기의 5S 원칙이 Lean의 토대가 되었다.

5S 원칙

  1. Seiri or Sort(정리 혹은 정렬) : 알맞은 명명법을 통해 어디에 무엇이 있는지 파악할 수 있어야 한다.
  2. Section(정돈 혹은 체계화) : 물건(코드)은 누구나 예상하는 위치에 있어야 한다. 모든 것은 제자리가 있다.
  3. Seiso(청소 호은 광내기) : 과거 이력, 미래 바람이 써진 주석 과 주석처리 된 코드는 삭제한다.
  4. Seiketsu(청결 혹은 표준화) : 그룹 내 일관적인 구현 스타일과 기법의 필요성
  5. Shutsuke(생활화 혹은 규율) : 관례를 따르고, 자신의 결과물을 자주 돌아보고 기꺼이 변경하는 규율

제조업이란 메타포에서 재작업은 비용을 뜻하지만 소프트웨어 설계에서 재작업은 가치를 가져온다.


1장 깨끗한 코드

코드가 존재하리라

AI가 발전하여 대신 작성해 주더라도 코드는 사라지지 않는다. 코드는 요구사항을 상세하게 표현하는 수단이기 때문이다. 추상화 수준이 높아지고 DSL(Domain Specific Language)수가 많아져도 코드는 항상 존재할것이다.

나쁜 코드

나쁜 코드로 인해 회사가 망하기도 한다. 바빠서, 어려워서, 어떤 핑계로든 나중에 손보겠다라고 하지만 나중은 오지 않는다.

나쁜 코드로 치르는 대가

나쁜 코드로 인해 생산성은 점차 감소한다. 1가지를 고치면 여러 문제가 발생하기 시작한다.

원대한 재설계의 꿈

결국 현재의 유지보수와 재설계가 공존하게 된다. 이 재설계 또한 몇년이 걸릴지는 아무도 모른다.

태도

상사, 고객사 등 외부 요인으로 인해 시간에 쫒길수 도 있다. 하지만 어떤 이유가 됐든 나쁜코드를 이해하지 못하는 사람의 말을 따르는 것은 전문가답지 못하다. 마치 손을 씻지 말라는 환자의 요구를 듣는 의사처럼!

원초적 난제

모두가 나쁜 코드가 속도를 지연시킨다는 것을 알고 있다. 하지만 마감으 압박으로 인해 나쁜 코드를 양산한다. 역설적으로 나쁜 코드 때문에 결국 늦어진다. 빨라지는 길은 언제나 코드를 깨끗하게 유지하는것 뿐이다.

깨끗한 코드라는 예술?

깨끗한 코드와 그렇지 못한 코드를 구별하는 것과 작성할 줄 아는것, 수정할 줄 아는 것은 명백히 다르다. 어떻게 개선해야할지를 생각하고 실행해야 한다. 누군가는 재능이라 당연한 감각이겠지만, 없더라도 반드시 가져야만 한다.

깨끗한 코드란?

비야네 스트롭스트룹
  1. 논리가 간단하여 버그가 숨지 않는다.
  2. 의존성을 최소화하여 유지보수를 쉽게 한다.
  3. 명백한 전략으로 철저하게 오류를 처리한다.
  4. 원칙없는 최적화를 지양한다.
  5. 한 가지를 제대로 한다.
그래디 부치
  1. 단순하고 직접적이다.
  2. 잘 쓴 문장처럼 읽힌다.
  3. 설계자의 의도를 숨기지 않는다.
  4. 명쾌한 추상화와 단순하 제어문으로 가득하다.
데이브 토마스
  1. 누구나 읽고 고치기 쉽다.
  2. 단위 테스트와 인수 테스트 케이스가 존재한다.
  3. 특정 목적을 달성하는 방법은 단 하나만 제공한다.
  4. 의존성을 최소화하며 각 의존성을 명확히 정의한다.
  5. API도 명확하고 최소화 한다.
마이클 페더스
  1. 누군가 주의 깊게 짰다는 느낌을 준다.
  2. 딱히 고칠 곳이 없다.

책을 읽고

5주 짜리 팀 프로젝트를 하면서도 느꼈던 내용들이다. 사실 현업의 수준에 비해서 내 프로젝트의 코드는 너무 간단하고 기초적이다. 그럼에도 불구하고 내 코드는 분명 깨끗한 코드가 아니였다. 프로젝트 중반부에 다른 팀원에게 내 코드를 보여줄 때 너무 복잡하다는 피드백을 많이 들었다. 나조차도 내 코드를 파악하지 못하고 있었고, 어디에 무엇이 있는지 확신하지 못했었다.

알게된 것

애자일(Agile Software Development)

소프트웨어 개발 방법론의 하나이다. 소프트웨어의 규모가 커지고 복잡해질 수록 기존의 ‘Waterfall(폭포수)’ 방법론에서 발생하는 단점과 문제점으로 인해 나타난 방법론이다.

폭포수 모델(Waterfall) : 개발으 흐름이 폭포수처럼 아래로만 향한다.

타당성 검토 -> 계획 -> 요구 분석 -> 설계 -> 구현 -> 테스트 -> 유지보수 와 같은 방식으로 이루어진다.

폭포수 모델을 소프트웨어 개발에 적용하면서 생기는 문제들은 다음과 같다.

  • 개발에 적용할 수 있을 수준의 구체적인 요구사항을 작성하는 것이 매우 어려움. 불가능함.

  • 규모가 커질수록 설계에 요구되는 시간과 비용이 기하급수적으로 증대됨.
  • 실제로 개발에 들어가고나서 정해진 요구사항이 변경되거나, 다양한 문제점이 발견됨.
  • 위와 같은 문제로 인해 작업 난이도 및 개발일정을 예측하는 것이 어려움.

핵심은 개발과 함께 즉시 피드백을 받아서 유동적으로 개발한다는 것.

애자일 선언문은 다음과 같다.

We are uncovering better ways of developing software by doing it and helping others do it. Through this work we have come to value:

Individuals and interactions over processes and tools Working software over comprehensive documentation Customer collaboration over contract negotiation Responding to change over following a plan

That is, while there is value in the items on the right, we value the items on the left more. © 2001, the Agile Manifesto authors This declaration may be freely copied in any form, but only in its entirety through this notice.

애자일 소프트웨어 개발 선언 우리는 소프트웨어를 개발하고, 또 다른 사람의 개발을 도와주면서 소프트웨어 개발의 더 나은 방법들을 찾아가고 있다. 이 작업을 통해 우리는 다음을 가치 있게 여기게 되었다:

공정과 도구보다 개인과 상호작용을 포괄적인 문서보다 작동하는 소프트웨어를 계약 협상보다 고객과의 협력을 계획을 따르기보다 변화에 대응하기

가치 있게 여긴다. 이 말은, 왼쪽에 있는 것들도 가치가 있지만, 우리는 오른쪽에 있는 것들에 더 높은 가치를 둔다는 것이다. Kent Beck, Mike Beedle, Arie van Bennekum, Alistair Cockburn, Ward Cunningham, Martin Fowler, James Grenning, Jim Highsmith, Andrew Hunt, Ron Jeffries, Jon Kern, Brian Marick, Robert C. Martin Steve Mellor, Ken Schwaber, Jeff Sutherland, Dave Thomas © 2001, 상기 저자들 이 선언문은 어떤 형태로든 자유로이 복사할 수 있지만, 본 고지와 함께 전문으로서만 가능하다.

익스트림 프로그래밍(XP, Extreeme Programming) 과 테스트 주도 개발(TDD, Test Driven Development)가 대표적인 예시이다.

TDD(Test Driven Development)

테스트 주도 개발. 코드 작성 전에 테스트 케이스를 먼저 작성하고, 이 테스트를 통과하는 코드를 작성하는 개발 방법론. 개발이 이루어진 다음 잘 작동하는지 테스트 케이스로 확인하는 방식이 아니다. 당연히 하나의 테스트가 완전하지 않기 때문에 계속해서 새로운 테스트 케이스를 확장해서 작성하고 그것에 맞추어 개발하는 과정을 반복하게 된다.

장점

  • 코드의 유지보수가 용이해진다.
  • 프로그래밍 시간이 단축된다.
  • 뛰어난 프로그램 소스코드 기록

스크럼(Scrum)

애자일 개발 방법론 중 하나. 프로젝트를 작은 단위로 나누고 이를 짧은 주기로 진행하는 방식. ‘스프린트’라는 시간 단위로 작업을 계획하고 수행. 정기적인 회의를 통해 프로젝트의 진행 상황 점검. 소프트웨어 개발 프로젝트를 위해 고안되었지만 유지보수 팀이나 프로젝트/프로그램 관리에도 적용 될 수 있다. 기능/개선점에 대해 우선순위를 부여하고 개발 주기(예를 들어, 30일)마다 실제 동작할 수 있는 결과를 제공하고, 목록을 업데이트 한다. 매일 회의를 가지고, 원활한 의사소통에 신경써야 한다.

휴리스틱(heuristic)

문제를 해결하거나 불확실한 사항항에 대해 판단을 내릴 필요가 있지만, 명확한 실마리가 없을 경우에 사용하는 편의적, 발견적인 방법을 말한다. 불충분한 시간이나 정보로 인하여 합리적인 판단을 할 수 없거나, 체계적이면서 합리적인 판단이 굳이 필요하지 않은 상황에서 사람들이 빠르게 사용할 수 있게 보다 용이하게 구성된 간편추론의 방법이다. Rule of Thumb도 휴리스틱의 일종이라고 볼 수있다고 한다. 정확하고 논리적으로 도출된 결론보단 경험칙등을 통해 얻은 방법론을 뜻하는 듯 하다. 안티 바이러스 프로그램에서 기존에 존재하지 않은 신종 악성코드를 발견하기 위해서 사용된다. 단어 자체는 “경험적인, 스스로 발견하게 하는” 이라는 뜻이다.

Rule of Thumb

17세기 영국 관습법 중 하나다. 결혼한 남자가 집안의 규율을 위해 여자를 막대기로 다스릴 수 있는데, 단 그 막대기가 엄지 두께보다 두꺼워선 안된다는 법이다. 현재는 일반적인 규칙이나 사실을 쉽게 전달하기 위해 사용하는 용어를 뜻함. 정확하게 과학적인 잣대로 재거나 법으로 규정지어진 것이 아니지만 현실에 어느정도 융통성있게 적용되는 ‘삶의 지혜’를 말한다. ‘체 했을 떈 손가락을 따야해. 그게 Rule of Thumb야.’ 정도로 쓰일 수 있을 듯 하다.

DSL(Domain-Specific Language)

특정 도메인에 대한 문제를 해결하기 위해 설계된 언어. 일반적인 프로그래밍 언어보다 간결하고 이해하기 쉬운 문법을 가짐.

장점

  • 도메인 수준에서 검증, 확인 가능하고 그 분야의 사람들 간에는 이해하고 소통하기 쉽다.

단점

  • 새로운 언어를 배우는 초기 비용과 좁은 적용분야

르블랑의 법칙(Leblance’s Law)

Meir “Manny” Lehman이라는 컴퓨터 과학자가 말한 법칙이다. “모든 것은 변한다”라는 내용의 컴퓨터과학에서의 관찰된 법칙. 소프트웨어의 요구사항, 기능, 소프트웨어 개발에 사용되는 도구 및 기술 등, 소프트웨어 개발에서 모든 것이 지속적으로 변한다는 것. 이 책에서 과거에는 이 법칙을 몰랐다고 말한다. 모든 것은 변하니 나중으로 미루지 말고 지금 당장 깨끗한 코드를 작성하라고 말하고자 인용되었다.

Lean 원칙(Lean Production)

도요타 생산 방식(TPS, Toyota Production System)을 말하는데, JIT(Just in time) 생산 방식이라고도 불린다. 최고, 최대의 원가절감을 위한 시스템이다.

린 공정 설계 (Lean Process Design)

5가지 주요 원칙이 있다.

  1. Value : 고객이 제품이나 서비스에 대해 얼마나 지불할 것인지를 정의하고 이해한다.
  2. Value Stream : 제품이나 서비스를 생성하고 고객에게 전달하는데 필요한 모든 과정을 식별하고 분석하는 가치 흐름을 파악한다. 비효율적인 과정이나 불필요한 과정을 제거한다.
  3. Flow : 공정을 최적화하고 끊김 없이 가치를 생성하는 흐름을 만든다. 시간과 자원 낭비를 제거한다.
  4. Pull : 고객의 요구에 따라 생산을 조절한다. 과잉 생산을 방지하고 고객의 실제 요구에 응답한다.
  5. Perfection : 지속적인 개선을 통해 완벽한 공정과 제품을 추구한다.

린 개발원칙

이것이 개발방법론으로 발전하여 7개의 개발원칙이 되었다.

  1. Eliminate Waste(낭비제거) : 불필요한 코드/기능, 불분명한 요구사항 등 S/W 가치에 영향이 없는 모든 것을 제거
  2. Amplify Learning(배움증폭) : 프로세스 진행 중 참여자(기획자, 개발자, 사용자 등) 학습의 필요성 존재
  3. Decide As Late As Possible(늦은결정) : 주요문제에 대한 의사결정을 최대한 연기함으로써 요구사항변경에 적극적으로 대응
  4. Deliver As Fast As Possible(빠른인도) : 결과물을 가능한 빨리 제공하는 것이 도움. 불확실성 감소(사용자측면), 결함발견의 기회(개발자측면)
  5. Empower The Team(팀에권한위임) : 팀원들의 동기부여 및 자기의사결정권으로 잠재력 극대화
  6. Build Integrity In(통합성구축) : 개발 초기부터 지속적인 통합으로 품질 향상, 소규모 개발단계마다 오류 발견 및 수정
  7. See The Whole(전체최적화) : 요구사항수집부터 S/W 배포까지 모든 프로세스 최적화