좋은 코드, 나쁜 코드 1장

 

좋은 코드, 나쁜 코드 [1장] 

코드 품질

  • 고품질 코드
    • 신뢰할 수 있는 코드
    • 유지보스가 용이
    • 버그가 적은 소프트웨어를 생산
    • 요구사항에 유연하게 대처
  • **저품질 코드**
    • 요구사항 에 대규모의 코드 변경 및 리팩터링이 필요
    • 시스템이 미리 정의되지 않은 상태에 놓이고 손상될 가능성이 있음
  • 코드는 어떻게 소프트웨어가 되는가
    • 코드는 일반적으로 엔지니어가 작성하자마자 실제로 실행되는 소프트웨어가 되지 않는다.
    • 코드가 의도한 대로 작동하고 기존의 기능이 여전히 잘 동작하기 위해서 다양한 과정과 점검이 이루어진다.
    • 이러한 과정을 소프트웨어 개발 및 배포 프로세스라고 한다.
    • 코드베이스 : 소프트웨어를 빌드할 수 있는 코드가 저장된 저장소
      • git, subversion, perfore와 같은 형상 관리 시스템으로 관리됨
    • 코드 제출 : 코드 커밋, 풀 요청 병합이며 일반적으로 코드베이스를 자신의 로컬 컴퓨터에 복사하고, 여기서 코드를 변경하며 코드를 메인 코드베이스에 제출한다.
    • 코드 검토 : 코드 리뷰 과정이며 다른 엔지니어가 변경된 내용을 검토하도록 한다. 코드 작성자가 놓친 문제를 점검할 수 있다.
    • 제출 전 검사 : 병합 전 혹(pre-merge hook), 병합 전 점검(pre-merge check), 커밋 전 점검(pre-commit check)라고 하며, 테스트가 실패하거나 코드가 컴파일되지 않을 경우 변경 사항이 코드베이스에 병합되지 않도록 차단한다.
    • 배포(release) : 소프트웨어는 코드베이스의 스냅숏을 기반으로 빌드된다. 다양한 품질 보증 검사 후 실제 실행 환경에 배포되며, 특정 버전을 가져와서 배포하는 프로세스를 배포 브랜치 만들기(cutting release)라는 문구를 자주 사용한다.
    • 프로덕션 : 소프트웨어가 서버나 시스템에 배포될 때, 테스트 환경과 같이 내부적으로 사용하는 것이 아닌 실제 서비스되는 환경을 가리킨다. 소프트웨어가 비즈니스 관련 작업을 수행하면 프로덕션 환경에서 실행된다고 할 수 있다.

  • 코드는 작동 되어야 한다.
  • 코드는 변경된 요구 사항에 적응할 수 있어야 한다.
    • [요구사항이 변하는 과정]
      • 비즈니스 환경이 변한다.
      • 사용자 선호가 변한다.
      • 가정이 더 이상 유효하지 않다.
      • 새로운 기능이 계속 추가된다.
  • 코드는 이미 존재하는 기능을 중복 구현해서는 안 된다.
    • [파일을 다시 저장하는 경우 아래와 같은 환경이 발생]
      • 파일에서 바이트 데이터를 로드
      • 바이트 데이터를 분석해서 이미지 형식으로 변환
      • 이미지를 흑백으로 변환
      • 이미지를 다시 바이트로 변환
      • 바이트 데이터를 파일로 저장
    • 이는 대부분 프로그래밍 언어에서 지원하거나, 라이브러리가 존재한다.
    • 이를 재사용하여 아래와 같은 이점을 얻을 수 있다.
      • 시간과 노력을 절약
      • 버그 가능성 감소
      • 기존 전문지식 활용
      • 코드 이해가 쉬워짐
  • **코드 품질의 핵심 요소**
    • 코드는 읽기 쉬워야 한다.
    • 코드는 예측 가능해야 한다.
      • 코드가 무슨 일을 하는지, 입력값으로 무엇을 예상하는지, 무엇을 반환하는지에 대한 정신 모델을 구축해야 한다.
      • 아무리 좋은 의도를 가진 코드라도 예측할 수 없는 일을 한다면, 그 상황에 대처할 생각을 하지 못할 것이다.
    • 코드를 오용하기 어렵게 해야 한다.
    • 코드를 모듈화 해야한다.
    • 코드를 재사용 가능하고 일반화할 수 있게 작성해야 한다.
      • 재사용성과 일반화성은 다른 개념을 가지고 있다.
        • 재사용성 : 어떤 문제를 해결하기 위한 무언가가 여러 가지 다른 상황에서도 사용될 수 있음을 의미
        • 일반화성 : 개념은 유사하나 서로 미묘하게 다른 문제들을 해결할 수 있음을 의미
        • 드릴의 경우 구멍을 뚫는 다는 기능이 있어서 여러 곳에 적용할 수 있다. (재사용성)
        • 드릴이 앞에 파츠만 교체한다면 나사도 박을 때 사용 가능하다 (일반화성)
    • 테스트가 용이한 코드를 작성하고, 제대로 테스트 해야한다.
      • 단위 테스트 : 개별 함수나 클래스와 같은 작은 단위의 코드를 테스트한다.
      • 통합 테스트 : 시스템이 여러 구성 요소, 모듈, 하위 시스템으로 구성될 때, 구성 요소와 하위 시스템을 함께 연결하는 과정
      • 종단간 테스트 : 처음부터 끝까지 전체 소프트웨어 시스템에서 작동되는 흐름을 테스트한다.
      • **테스트 용이성** : 테스트 대상이 되는 실제 코드를 가리키며 해당 코드가 얼마나 테스트하기 적합한지를 나타낸다.
        • 코드를 다 작성하고 테스트하는 것은 용이하지 않다.
        • 어떻게 테스트할 것인가를 계속 자문하는 것이 좋다.
  • 고품질 코드 작성은 일정을 지연시키는가?
    • 적절한 방법과 임시변통인 방법에 대해 생각해야 한다.
    • 장기적인 방법이 더 번거로움을 줄여줄 가능성이 크다.
    • 코드 품질을 고려하지 않고 먼저 떠오르는 대로 코딩하는 것을 피해야 한다.
    • 좋은 소프트웨어를 만들려면 고품질 코드를 작성해야 한다.
    • 실제 서비스 환경에서 실행되려면 일반적으로 여러 단계의 검사와 테스트를 통과해야 한다.