본문으로 건너뛰기

프로그래밍의 정석 요약

· 약 50분
karais89

프로그래밍의 정석 요약

책에서의 용어 설명

  • 모듈
    - 함수나 변수를 어떤 책임 단위로 묶어낸 것은 모듈로 통일한다.
    연관성이 높은 코드를 한데 묶었다는 의미에서 클래스, (함수나 변수를 모은 하나의) 파일, 컴포넌트, 부품, 라이브러리라는 용어도 있는데, 이 용어들을 모두 포함해서 모듈이라고 부른다.
  • 함수
    - 코드 일부를 떼어내어 호출할 수 있게 만든 것은 함수로 통일한다.
    루틴, 함수, 프로시저, 메시지, 메서드, 멤버 함수 등 용어는 세부적으로 나뉘는데, 이 용어들은 모두 포함해서 함수라고 한다.

책에서의 참고 서적

원리 원칙 리스트

  • 프로그래밍에 은제 탄환은 없다
    • 프로그래밍에 마법 같은 해결책은 없다.
  • 코드는 설계서다
  • 코드는 반드시 변경된다
    • 코드가 변경된다는 사실은 코드를 작성할 때 다양한 판단, 선택, 결단을 하는 데 있어서 최우선으로 고려해야 한다.
  • KISS (Keep It Simple, Stupid / Keep It Short and Simple)
    • 간단하게 해라, 어리석은 녀석아 / 간결하고 단순하게 해라
    • 코드를 작성할 때는 최우선 가치를 단순성과 간결성에 둔다.
  • DRY (Don't Repeat Yourself 중복하지 마라)
    • 똑같은 코드를 중복해서 작성해서는 안된다
  • YAGNI (You Aren't Going to Need it 그것은 분명 필요 없어진다)
    • 정말로 필요해졌을 때 필요한 코드만을 작성한다는 방침으로 프로그래밍에 임해야 한다
  • PIE (Program Intently and Expressively 의도를 표현해서 프로그래밍하라)
    • 코드를 작성할 때는 의도를 명확하게 표현해야 한다는 점이 중요하다
    • 코드는 컴파일러가 아닌 사람이 읽기 위한 것이기 때문이다
    • 코드를 작성할 때는 작성하기 쉬움 보다는 읽기 쉬움을 중시하자.
  • SLAP (Single Level of Abstraction Principle 추상화 수준의 통일)
    • 추상화 단계를 분리할 때는 기능의 복잡도에 따라 여러 계층으로 분리한다.
  • OCP (Open-Closed Principle 개방-폐쇄의 원칙)
    • 코드는 확장에 대해서 열려 있고 수정에 대해서 닫혀 있는 2가지 속성을 동시에 충족하도록 설계한다
    • 확장에 대해서 열려 있다는 말은 코드의 동작을 확장할 수 있다는 의미이다.
    • 수정에 대해서 닫혀 있다는 말은 코드의 동작을 확장하더라도 그 밖의 코드는 전혀 영향을 받지 않는다는 의미이다.
    • 코드에 인터페이스를 사용한다
    • OCP의 대표적인 패턴 (스트레티지, 옵저버, 탬플릿 메서드,데코레이터)
  • 명명이 중요하다
    • 이름을 붙이는 행위와 그런 과정을 통해 생겨난 이름 자체에 모두 중요한 가치가 있다.
    • 다음 사항에 주의한다.
      • 이름에는 더 많은 정보를 담도록 한다. 이름을 짧은 주석이라고 생각한다.
      • 이름을 오해받지 않도록 주의한다. 다른 의미와 혼동되지 않도록 몇 번이고 자문자답해야 한다.
      • 이름이 효과와 목적을 설명하도록 한다.
      • 이름은 발음 가능한 것으로 한다
      • 이름은 검색 가능하도록 붙인다.
  • 프로그래밍 이론
    • 최고의 코드란 확장 방법이 다양하게 존재하고 불필요한 요소가 존재하지 않으며 읽기 쉽고 이해하기 쉬운 코드다.
      • 의사소통
        • 코드는 남에게 보여주는 문서다. 그리고 문서의 본질은 의사소통 수단이다.
        • 프로그래밍에서 의사소통이 원할하다는 것은 코드를 읽은 사람이 코드를 이해할 수 있고, 코드를 수정할 수 있으며, 코드를 사용할 수 있다는 뜻이다.
      • 단순함
        • 코드가 단순하다는 것은 코드에서 불필요한 복잡성이 제거된 상태를 가리킨다.
      • 유연성
        • 코드에서 유연성이란 코드 변경이 용이함을 뜻한다.
  • 결과의 국소화
    • 변경이 미치는 영향이 국소에 머무르도록 코드를 구성한다.
  • 반복의 최소화
    • 반복이란 중복을 뜻한다. 즉 중복을 최대한 제거한다는 뜻이다.
  • 로직과 데이터의 일체화
    • 로직과 해당 로직이 조작하는 데이터를 서로 가까이에 배치시키는 것을 뜻한다.
    • 여기서 가까이란 같은 함수 혹은 같은 모듈이며 가까우면 가까울수록 좋은 코드다.
  • 대칭성
    • 대칭성이란 일반적으로 어떤 변환에도 변하지 않는 성질을 가리킨다.
  • 선언형의 표현
    • 선언형의 표현이란 코드의 의도를 전하고자 할 때 가능한 한 명령형보다는 선언형으로 표현하는 것을 뜻한다.
    • 명령형 프로그램은 문제의 해법, 즉 자료구조와 알고리즘을 기술한다.
    • 반면에 선언형 프로그래밍은 문제의 정의, 즉 해결해야 할 문제의 성질이나 이때 충족해야 할 제약을 기술한다.
  • 변경빈도
    • 변경 빈도란 코드를 수정하는 시점이 같다는 의미이다. 즉 변경 이유가 같다는 뜻이다.
    • 같은 시점에 변경되는 요소는 같은 곳에 두고, 다른 시점에 변경되는 요소는 다른 곳에 분리해 두도록 한다.
  • 아키텍처 기본 기법
    • 소프트웨어 아키텍처를 적절하게 구축하는 데 필요한 기초 원리
    • 추상
      • 추상이란 개념적으로 명확한 선 긋기를 수행하는 것이다.
      • 추상은 사상과 일반화라는 2가지 관점에서 정리된다.
        • 사상 : 복잡한 대상의 몇 가지 성질을 버리고 특정한 성질에 주목하는 것
        • 일반화 : 구체적인 대상으로부터 공통 성질을 추출해서 더욱 범용적인 개념으로 정싱화하는 것
    • 캡슐화
      • 관계성이 강한 데이터와 로직을 모듈이라는 껍질로 감싸는 것을 캡슐화라고 부른다.
    • 정보 은닉
      • 모듈의 구현을 해당 모듈을 사용하는 클라이언트로부터 은닉한다.
    • 패키지화
      • 모듈을 의미 있는 단위로 모은 다음 그룹화한다.
    • 관심의 분리
      • 관심이란 소프트웨어의 기능이나 목적을 뜻한다.
      • 관심을 분리한다는 것은 각각의 관심에 관련된 코드를 모아 독립된 모듈로 만들어 다른 코드로부터 분리한다는 뜻이다.
      • 대표적인 패턴 MVC
    • 충족성, 완전성, 프리미티브성(원시성, 순서성)
      • 모듈이 담당하는 추상에 대한 표현은 충분하고 완전하며 프리미티브여야 한다.
      • 충족성
        • 모듈이 표현하고자 하는 추상이 그것을 전하기에 충분한지를 뜻한다.
        • 모듈이 컬렉션을 표현하고 있을 때 remove가 제공된다고 해도 add가 제공되지 않는다면 컬렉션이라는 점을 전하기에는 불충분하다.
      • 완전성
        • 모듈이 표현하고자 하는 추상이 모든 특징을 갖추고 있는지를 뜻한다.
        • 모듈이 컬렉션을 표현하고 있을 때 요소의 개수를 구하는 size가 제공되지 않는다면 완전하다고 할 수 없다.
      • 프리미티브성
        • 모듈이 표현하고자 하는 추상이 모두 순수한지 아닌지를 의미한다.
        • 모듈이 컬렉션을 표현하고 있을 때 아이템을 1개 추가하는 add가 제공된다면 아이템을 10개 추가하는 add10은 필요하지 않다.
    • 정책과 구현의 분리
      • 모듈은 정책 혹은 구현을 다룬다. 다만 하나의 모듈에서 양쪽 모두를 다루어서는 안 된다.
    • 인터페이스와 구현의 분리
      • 모듈은 인터페이스 파트와 구현 파트 2개의 분리된 부분으로 구성한다.
        • 인터페이스 파트 : 모듈이 가진 기능을 정의하고 모듈의 사용 방법을 정하는 부분 클라이언트에서 접근할 수 있는 함수의 원형으로 구성된다.
        • 구현 파트 : 구현 파트란 모듈이 가진 기능을 실현하는 코드 부분. 모듈이 내부에서 사용하는 로직과 데이터가 포함된다. 구현 파트는 클라이언트에서 접근할 수 없다.
      • 사용자는 인터페이스만 알면 된다.
    • 참조의 단일성
      • 모듈의 요소에 관한 선언과 정의는 1회로 제한한다
      • 정의가 1회라는 말은 예를 들어 변수값을 초기화했다면 이후 값은 변경하지 않는다는 뜻이다.
      • 이렇게 하면 변수값의 변화를 추적하지 않아도 되므로 직관적인 코드가 된다.
    • 분할 정복
      • 그대로는 해결하기 어려운 커다란 문제는 여러 개의 작은 문제로 분할해서 개별적으로 해결한다
  • 아키텍처 비기능 요구사항
    • 정의: 기능 외적인 면 전반에 관한 요구사항
    • 변경 용이성
      • 변경 용이성이란 해당 소프트웨어를 얼마나 쉽게 개선할 수 있는지에 대한 능력
      • 해당 소프트웨어를 쉽게 수정할 수 있는지, 쉽게 확장할 수 있는지, 쉽게 재조직할 수 있는지, 쉽게 다른 플랫폼으로 이식할 수 있는지 등의 능력
    • 상호 운용성
      • 상호 운용성이란 소프트웨어가 다른 소프트웨어와 정보를 주고받을 수 있는 능력
    • 효율성
      • 효율성이란 소프트웨어가 실행되면서 동반되는 리소스 사용에 있어서 적절한 성능을 끌어내는 능력
      • 시간 효율성
      • 자원 효율성
    • 신뢰성
      • 신뢰성이란 소프트웨어가 예외적인 상황 혹은 예기치 못한 방법이나 부정한 방법으로 사용된 상황에서도 기능을 유지하는 능력
    • 테스트 용이성
      • 테스트 용이성이란 소프트웨어에 대해 효과적이면서 효율적으로 테스트를 수행하는 능력
    • 재사용성
      • 재사용성이란 소프트웨어를 전체가 됐든 일부가 됐든 다른 소프트웨어 개발에 재사용하는 능력을 뜻한다.
  • 7가지 설계 원리
    • 7가지 설계 원리란 결함을 만들어 내지 않기 위해 고려해야 할, 코드 구조상의 7가지 핵심 관점을 뜻한다.
    • 단순 원리
      • 단순 원리란 단순함을 중시한다는 원리다.
      • 극단적으로 말하자면 프로그래밍 생초보도 읽을 수 있을 만큼 일관되고 단순한 코드를 작성해야 한다.
    • 동형 원리
      • 동형 원리란 형태를 중시한다는 원리다.
      • 어떤 모듈에서 다루는 숫자의 단위, 공개 함수의 파라미터 수, 사용 순서 등이 통일된다는 것을 의미한다.
      • 일관성 있는 코드를 작성하자.
    • 대칭 원리
      • 대칭 원리란 형태의 대칭성을 중시한다는 원리다.
      • 어떤 플래그가 참일 때의 처리가 있다면 거짓일 때의 처리도 있어야 한다.
      • 명명의 대칭성에도 신경 쓰자. set/get, start/stop, begin/end, push/pop 등
    • 계층 원리
      • 계층 원리란 구조의 계층성을 중시한다는 원리다.
      • 리소스를 할당했다면 같은 계층에서 리소스를 해제해야 한다.
      • 배타 제어를 위해 플래그를 걸었다면 같은 계층에서 플래그를 해제해야 한다.
    • 선형 원리
      • 선형 원리란 처리의 직선적 흐름을 중시한다는 원리다.
      • 오류는 복잡한 조건문이나 반복문에서 많이 발생한다.
      • 위에서 아래를 향해 한 방향으로 내려가는 코드 흐름은 단순명쾌하고 이해하기 쉽다.
      • 분기가 적은 코드를 작성한다.
    • 명증 원리
      • 명증 원리란 로직의 명증성을 중시한다는 원리다.
      • 명증성이란 확실하게 증명한다는 의미다.
    • 안전 원리
      • 안전 원리란 안전성을 중시한다는 원리다.
      • 필연성이 없는 곳이나 모호한 곳은 안전한 쪽으로 설계하고 프로그래밍해 두는 것이다.
  • UNIX 사상
    • UNIX 사상이란 뛰어난 프로그래밍을 수행할 수 있는, 경험에 기반을 두고 있는 실천적인 노하우의 집합이다.
    • 모듈화의 원칙
      • 명료한 인터페이스로 결합한 단순한 모듈들로 소프트웨어를 조립해야 한다
      • 코드 중에 관계성이 높은 요소를 모아 모듈을 작성한다
      • 모듈이 제공하는 인터페이스는 불필요한 것은 제외하고 가장 적게 만들자
      • 모듈의 구성 요소는 관계성이 높은 것만 모아 놓도록 한다.
    • 명확성의 원칙
      • 코드는 교모하게가 아니라 명확하게 작성해야 한다
    • 구성의 원칙
      • 소프트웨어는 다른 소프트웨어와 조합할 수 있도록 만든다
    • 분리의 원칙
      • 메커니즘에서 정책을 분리한다.
      • 정책
        • 해당 소프트웨어의 전제에 종속되는 부분
        • 비즈니스 로직이나 사용자 인터페이스
      • 메커니즘
        • 해당 소프트웨어의 전제에 종속되지 않는 독립된 부분
        • 그래픽 처리의 래스터 변환 등 엔진 역할을 수행하는 부분
    • 단순성의 원칙
      • 코드가 단순해지도록 설계한다
    • 절약의 원칙
      • 큰 코드는 작성하지 않도록 한다
      • 코드의 분량이 큰 것과 코드 내부의 복잡도가 큰 양쪽을 의미한다.
    • 투명성의 원칙
      • 소프트웨어의 동작을 바깥에서 이해하기 쉽게 보이도록 설계한다
    • 안전성의 원칙
      • 일반적인 조건뿐만 아니라 예상외의 조건에서도 적절하게 동작되는 것
    • 표현성의 원칙
      • 코드에서 정보를 표현할 때는 로직이 아닌 데이터에 모아 작성하는 방식으로 한다
    • 충격 최소의 원칙
      • 인터페이스는 사용하는 사람이 상상하는 형태대로 동작하도록 설계한다
    • 침묵의 원칙
      • 소프트웨어는 표시를 최소한으로 줄이고 과묵하게 작업을 수행해야 한다
    • 복구의 원칙
      • 소프트웨어 동작 중 오류 복구에 실패했다면 처리를 계속해서는 안 된다
      • 나아가 해당 오류는 가능하면 한눈에 띄도록 발생시킨다
    • 경제성의 원칙
      • 프로그래머의 시간을 절햑해야 한다
      • 시간 낭비가 되는 리스트
      • 빈약한 하드웨어
      • 사용 소프트웨어에 대한 제한
      • 환경에 관한 규제와 제한
    • 생성의 원칙
      • 코드를 작성하기 위한 코드를 작성한다
      • 코드 생성기를 만든다
    • 최적화의 원칙
      • 빠른 코드보다 바른 코드
    • 다양성의 원칙
      • 소프트웨어에서는 선택의 다양성을 수용한다
      • 소프트웨어에 관한 모든 상황에서 유일하게 바른 방법은 존재하지 않는다
      • 더 좋은 방법을 계속 찾는다
    • 확장성의 원칙
      • 확장성을 고려한 설계를 수행한다
  • UNIX 철학
    • UNIX적인 사고방식
    • 작은 것이 아름답다
      • 작게 만들고 작게 유지하도록 한다
      • 장점
        • 이해가 쉽다
        • 보수가 쉽다
        • 머신 자원에 부담을 주지 않는다
        • 다른 소프트웨어와 조합하기 쉽다
    • 한 번에 하나의 작업
      • 하나의 소프트웨어에는 하나의 작업만 제대로 시킨다
      • 가장 좋은 소프트웨어란 생애 중에 단 하나의 작업만을 제대로 완수하는 소프트웨어다
    • 즉시 프로토타입 진행
      • 가능한 한 빨리 프로토타입을 작성한다
      • 어떤 아이디어가 성공할 것 같은지, 눈에 보이는 형태로 현실화 할 수 있는지를 확인하려면 시험 삼아 만들어보는 방법이 가장 좋다
    • 효율성보다 이식성
      • 소프트웨어 설계는 선택의 연속이다
      • 이식성과 개발 효율성이라는 이율배반적인 선택을 해야되는데 이때는 이식성을 우선시해야 한다
    • 데이터는 텍스트로
      • 데이터는 텍스트 파일로 저장한다
      • 데이터의 이식성도 중시해야 한다
      • 거의 모든 면에서 바이너리 파일보다 뛰어나다
    • 레버리지 소프트웨어
      • 레버리지(지렛대)
      • 코드를 대량으로 작성하는 가장 좋은 방법은 빌려 오는 것이다
      • 각각이 단일 기능이며 단일 가치에 집중하는 작은 소프트웨어를 작성하자
    • 셸 스크립트 활용
      • 셸 스크립트를 통해 지렛대 효과와 이식성을 높인다
      • 셸 스크립트는 이식성이 높다
    • 대화형 인터페이스 회피
      • 대화형 인터페이스 회피
      • 지나친 대화형 인터페이스를 피하도록 한다
      • 대화형 인터페이스의 문제
        • 소프트웨어별로 독자적인 대화 방법을 기억해야 한다
        • 소프트웨어끼리 대화할 수 없다
        • 대기 시간이 많아진다
        • 입력 부분에 대한 해석 코드가 많아지고 흉해진다
        • 큰 것이 아름다운 접근법으로 변질된다
    • 필터화
      • 모든 소프트웨어를 필터로 설계한다
      • 필터란 입력 스트립을 데이터로 받아들여 어떤 형태로든 가공한 다음 가공된 데이터를 출력 스트림으로 송출하는 것이다
      • 소프트웨어의 본질은 데이터를 처리하는 것이지 생성하는 것이 아니다
  • UNIX 철학과 작은 정리
    • 환경 커스터마이즈
    • 작고 가벼운 커널
    • 소문자 사용
    • 자연 보호
    • 침묵은 금
    • 병령 사고
    • 부품 협력
    • 90%의 해
    • 열등해야 뛰어나다
    • 계층 지향
  • 응집도
    • 응집도란 모듈에 포함된 기능의 순수함을 나타내는 척도로, 모듈의 강도를 측정하는 단위다
    • 응집도의 단계는 7단계다.
    • 단계가 높을수록(숫자가 클수록) 순수하고 강하며 좋은 모듈이다.
    • 1단계: 암합적 강도
      • 모듈 내 요소 간 특별한 관계가 인정되지 않는다
      • 암합이란 우연히 요소가 일치한다는 의미다
    • 2단계: 논리적 강도
      • 어떤 기능을 추상적으로 파악해서 모은 것이다
    • 3단계: 시간적 강도
      • 특정 시점에 연속해서 실행되는 여러 개의 기능을 하나의 모듈로 모은 것이다.
    • 4단계: 순서적 강도
      • 문제를 처리하기 위해 관계된 여러 개의 기능 중 몇 가지를 실행한다
    • 5단계: 연락적 강도
      • 기본적으로 순서적 강도의 특성을 갖는다
      • 순서적 강도와의 차이점은 모듈 내 기능 사이에서 데이터를 교환(연락)하거나 같은 데이터를 참조한다는 점이다.
    • 6단계: 정보적 강도
      • 특정 자료구조를 다루는 여러 개의 기능을 하나의 모듈로 모은 것이다.
    • 7단계: 기능적 강도
      • 모듈 내의 모든 명령이 하나의 역할(기능)을 실행하기 위해 서로 관련된 모듈로, 응집도가 가장 높은 모듈이다
  • 결합도
    • 결합도란 모듈끼리 갖는 관계의 밀접함을 나타내는 척도로, 어떤 결합의 굵기를 측정하는 단위다
    • 결합도의 수준은 6단계다.
    • 단계가 높을수록(숫자가 클수록) 관계가 약하고 느슨한 결합이며 좋은 모듈이라고 할 수 있다
    • 1단계: 내용 결합
      • 한 모듈과 다른 모듈이 일부를 공유하는 모듈 결합 방식
      • 다른 모듈 내의 외부에 선언되지 않은 데이터를 직접 참조하거나 명령의 일부를 공유하는 경우
    • 2단계: 공통 결합
      • 공통 영역에 정의된 데이터를 몇 개 모듈이 공동으로 사용하는 모듈 결합 방식
      • 공통 영역에 정의된 데이터란 이른바 전역 변수를 말한다
    • 3단계: 외부 결합
      • 외부에 선언된 데이터를 공유하는 모듈 결합 방식
      • 외부에 선언된 데이터란 예를 들면 public으로 선언된 변수를 말한다
    • 4단계: 제어 결합
      • 호출하는 모듈 쪽에서 호출받는 모듈의 제어를 지시하는 데이터를 파리미터로 넘겨주는 모듈 결합 방식
    • 5단계: 스탬프 결합
      • 공통 영역에 없는 자료구조를 2개의 모듈에서 교환하는 모듈 결합 방식
    • 6단계: 데이터 결합
      • 모듈 간의 인터페이스로 스칼라형 데이터 요소만을 파라미터로 교환하는 모듈 결합 방식
      • 모듈 A는 모듈 B의 입력으로 X를 넘겨주면 출력으로 Y를 받는다는 점만 알고 있다
    • 느슨한 결합을 지향하자
      • 데이터는 가능한 한 파라미터로 넘겨준다
      • 데이터는 가능한 한 전역 변수로 두지 않는다. 특정 시점에만 필요한 데이터라면 지역 변수로 두도록 한다
      • 넘겨주는 값에 따라 동작이 바뀌는 코드를 작성하지 않는다. 예를 들어 파라미터로 건네받는 플래그의 내용이 A라면 추가, D라면 삭제하는 식의 함수는 결합도가 강해진다
  • 직교성
    • 직교는 기하학에서 그래프의 좌표축과 같이 직각으로 교차하는 2개의 선분이 갖는 성질이다
    • 코드 간에는 독립성과 분리성을 갖도록 만든다
    • 2개 이상의 코드 덩어리가 있으면서 한쪽을 변경해도 다른 쪽에 영향을 주지 않는다면 해당 코드는 직교하고 있다
    • 직교하고 있는 코드는 변경에 강한 코드다
    • 장점
      • 생산성 향상
      • 위험 경감
  • 가역성
    • 가역이란 어떤 변화가 발생해도 특정 조건을 가하면 원래 상태로 돌아오는 성질
  • 코드의 구린내
    • 코드의 구린내란 코드 중에서 이해하기 어렵고, 수정하기 어렵고, 확장하기 어렵다고 느껴지는 부분
    • 프로그래머는 이런 구린내를 식별해 내서 적절한 코드로 개선해야 한다
    • 코드의 구린내 징후
      • 자주 보인다
        • 똑같은 코드가 여기저기 흩어져 있는 상태
      • 너무 길다
        • 함수가 너무 길어 스크롤을 몇 번이나 내려도 끝나지 않는 상태
      • 너무 크다
        • 모듈이 너무 컷거 관리 불능인 상태
        • 모듈이 너무 크다는 말은 해당 모듈이 담당하는 역할이 너무 크다는 뜻
      • 너무 많다
        • 모듈이 너무 많아서 관리 불능인 상태
        • 모듈이 크다는 이유로 지나치게 분해해서는 안 된다
      • 이름이 맞지 않는다
        • 이름과 실제 코드가 맞지 않는 상태
        • 이름은 중요하다
  • 기술적 부채
    • 문제 있는 코드는 '빚'이다
    • 프로그래밍의 2가지 길: 시간이 좀 걸리더라도 깨끗한 코드 or 신속하지만 지저분한 코드
    • 신속하고 지저분한 코드를 선택한다면 소프트웨어는 이른바 부채를 떠안는 셈이되는데 이를 기술적 부채라고 부른다
    • 기술적 부채는 코드에서 수정하기 어렵고 이해하기 어려운, 문제 있는 지저분한 코드 부분을 뜻한다
  • 프로그래머의 3대 미덕
    • 태만
      • 전체의 노력을 줄이기 위해 수고를 아끼지 않는 기질
      • 나중에 모두가 편해지도록 지금 유용한 코드를 작성한다
      • 반복 업무를 시스템화하자
      • 수작업에 관해서는 코드를 작성하고 툴을 만들어서 자동화 한다
    • 성급
      • 컴퓨터가 놀고 있는 것에 분노를 느끼는 기질
      • 일어날 수 있는 문제를 상정해서 업무를 하자
    • 오만
      • 천벌을 받을 정도로 넘치는 자존심을 지닌 기질
      • 높은 자존심을 갖고 남에게 내놓아도 부끄럽지 않은 코드를 작성한다
      • 남에게 부끄럽지 않게끔 작업하고 보수하자
  • 보이 스카우트 규칙
    • 코드는 자기가 왔을 때보다 깨끗이 하고 나서 자리를 떠나야 한다
    • 처음 코드를 작성한 사람이 누구인지와는 상관없이, 조금씩이라도 코드를 개선하려는 노력을 계속해야 한다
  • 성능 튜닝에 관한 금언
    • 프로그래밍에서는 빠른 코드보다 우선 바르고 읽기 쉬운 것에 주안점을 둔 좋은 코드를 작성하는 데 노력해야 한다
  • 비자아적 프로그래밍
    • 프로그래밍할 때는 자아를 떨쳐 버려야 한다
    • 자만과 자존심을 버리고 동료에게 협력을 구하도록 한다
    • 자신이 작성한 코드를 적극적으로 등료에게 보여주면서 개선점을 지적해 달라고 한다
    • 비자아적 프로그래밍의 십계
      • 자기 자신도 실수를 저지른다는 점을 이해하고 받아들인다
      • 작성한 코드는 자기 자신이 아니다
      • 아무리 끝까지 간 것 같아도 위에는 그 이상이 있다
      • 상담 없이 코드를 재작성하지 않는다
      • 자기보다 기술이 떨어지는 사람에게도 존경과 경의, 인내를 갖고 대한다
      • 세상에서 유일하게 변하지 않는 것은 변한다는 사실뿐이다
      • 진정한 권위는 지위가 아니라 지식에서 생겨난다
      • 신념을 위해 싸운다. 다만 패배는 깨끗이 수용한다
      • 방에 틀어박혀 있어서는 안 된다
      • 사람에게는 관대하고 코드에는 엄격하게, 사람이 아닌 코드를 비평한다
  • 한 걸음씩 조금씩
    • 프로그래밍은 한 번에 작은 하나만을 수행한다
    • 하나씩 조금씩 단차가 작은 계단을 올라가듯이 작업한다
    • 절대 한 번에 여러 가지 작업을 상대하지 말고 하나씩 처리한다
  • TMTOWTDI (There's more than one way to do it 방법은 하나가 아니다)
    • 다른 사람이 사용할 툴을 설계할 때는 달성하고자 하는 것의 수단을 여러 개 준비한다
    • 여기서 말하는 툴이란 프로그래밍 언어나 DSL, API를 가리킨다
  • 예광탄
    • 예광탄이란 빛을 발산함으로써 탄도의 궤적을 알 수 있게끔 만들어진 탄환을 말한다
    • 예광탄은 즉시 피드백을 가져다 준다
    • 프로그래밍에서의 예광탄이란 우선적으로 검증하고 싶은 부분을 선행적으로 프로그래밍하는 것이다
  • 계약에 의한 설계
    • 각각의 함수는 뭔가의 작업을 수행하는 것이다
  • 방어적 프로그래밍
    • 이렇게 될 것이다라고 결정짓지 말고 프로그래밍한다
    • 자동차의 방어 운전과 같은 사고방식이다
    • 외부 소스에서의 데이터 입력값을 확인한다
    • 함수의 입력 파라미터값을 확인한다
  • 개밥 먹기
    • 자기가 개발한 소프트웨어는 본인이 직접 사용해 봐야 한다
  • 고무 오리
    • 고무 오리는 일종의 디버깅 기법이다
    • 프로그래밍 중에 발생한 문제, 혹은 문제를 품고 있는 코드를 누군가에게 설명한다
    • 그러다 보면 문제의 원인을 스스로 깨닫고 자체 해결할 수 있을 때가 있다
  • 컨텍스트
    • 컨텍스트란 주위의 상황이나 배경을 뜻하며, 문맥이라고도 한다
    • 코드의 읽고 쓰기에 사용
    • 생각의 도구로 사용
  • 브룩스의 법칙
    • 일정이 늦어지고 있어 후반에 사람을 추가하면 오히려 지연이 한층 더 초래된다
  • 콘웨이의 법칙
    • 소프트웨어의 구조, 즉 아키텍처는 그것을 만든 조직을 반영한다
  • 깨진 유리창 법칙
    • 나쁜 설계, 잘못된 의사 결정, 나쁜 코드를 방치하면 그것이 아무리 작은 것이라도 소프트웨어 전체를 매우 단기간에 부패시킨다
  • 엔트로피 증가의 법칙
    • 엔트로피란 물리학 용어로 무질서한 정도를 나타낸다
    • 코드는 그대로 두면 한계를 뛰어넘을 만큼 무질서함이 증대된다
    • 코드의 부패 징후
      • 경직됨
        • 변경하기 어렵다
      • 깨지기 쉬움
        • 단 하나의 변경으로 인해 다른 많은 부분이 망가져 버리는 정도
      • 이식성 없음
        • 다른 환경으로 이식하기 어렵다
      • 다루기 어려움
        • 코드를 다루기 어려움과 개발 환경을 다루기 어려움이 있다
      • 복잡함
        • 불필요한 요소가 많음을 뜻한다
      • 반복
        • 똑같은 코드가 어러 번 반복해서 나타난다는 뜻이다
      • 불투명함
        • 코드를 이해하기 어렵다
  • 80:10:10의 법칙
    • 소프트웨어를 개발하면 사용자가 요구하는 것의 80%는 놀랄 만큼 단기간에 실현할 수 있다
    • 그러나 나머지 20% 중 10%는 실현은 가능하지만 상당한 노력이 필요하다
    • 더욱이 나머지 10%는 완전히 실현이 불가능하다
  • 조슈아 나무의 법칙
    • 사람은 이름을 아는 순간 그것이 보인다. 반대로 이름이 없으면(모르면) 그것은 보이지 않는다
  • 세컨드 시스템 증후군
    • 첫번째 버전을 배포한 프로그래머가 설계한 두번째 버전 소프트웨어는 해당 프로그래머가 설게하는 가장 위험한 버전이다
    • 두 번째 버전에는 기능을 너무 잔뜩 집어넣어 품질이 나쁘고, 기능의 사용성도 떨어지는 경향이 있다
  • 수레바퀴의 재발명
    • 이미 세상에 존재하는 수레바퀴를 일부러 수고를 들여 다시 한번 발명하는 것과 같은 쓸데없는 작업
    • 수레바퀴의 재발명을 피하고 본래 해야 할 작업에 주력하자
    • 코드를 작성하기 전에 똑같은 기능이 표준 라이브러리에 없는지, 오픈 소스 라이브러리에 없는지, 표준 프로토콜이 없는지를 반드시 확인하도록 한다
    • 수레바퀴를 재발명해야 될때
      • 비즈니스 목적
      • 학습 목적
  • 야크의 털깍기
    • 어떤 문제를 해결하려고 봤더니 다른 문제가 계속 나와 좀처럼 몸통, 즉 기본 문제(의 해결)에 도달하지 못하는 것이다
    • 야크의 털깍기는 기본적으로 피해 가야 한다