2.9

View in English

2.9 소프트웨어 구축

개요와 동기

소프트웨어 구축은 설계가 실행되는 코드가 되는 곳입니다. 코딩, 검증, 단위 테스트, 통합 테스트, 디버깅의 세부 작업입니다. 소프트웨어 엔지니어링 지식체계(SWEBOK) 가이드는 구축을 별개의 지식 영역으로 다루며, 이유가 있습니다. 일상 업무의 대부분이 여기서 일어나기 때문입니다. 줄마다 내리는 선택, 즉 복잡성을 어떻게 억제하는지, 오류를 어떻게 처리하는지, 얼마나 읽기 좋게 남기는지가 시스템을 앞으로 여러 해 동안 이해하고, 바꾸고, 신뢰할 수 있는지를 결정합니다.

큰 팀에서 구축은 혼자 하는 일이 아니라 집단의 노력입니다. 수백 명의 엔지니어가 어느 한 사람의 팀 재직 기간보다 오래 살 공유 코드베이스에 씁니다. 그래서 기준은 “오늘 내 머신에서 동작하는가”가 아닙니다. “낯선 사람이 5년 뒤 안전하게 바꿀 수 있는가”입니다. 구축은 위로는 무엇을 만들지와 그 모양을 알려 주는 요구사항(2.8장)과 설계(2.2장)에, 옆으로는 일이 어떻게 표현되고, 검증되고, 검사되는지를 형성하는 코딩 표준(2.1장), 테스트(2.4장), 코드 리뷰(2.5장)에 연결됩니다. 좋은 구축은 건전한 설계를 유지보수 가능한 자산으로 바꿉니다. 나쁜 구축은 좋은 설계마저 부채로 바꿉니다.

기업과 정부 환경에서 구축은 추가적인 무게를 집니다. 이런 시스템은 오래 살고, 크게 규제를 받고, 안전이나 시민에게 핵심적인 경우가 많습니다. 방어적 코딩, 규율 있는 오류 처리, 명백히 올바른 코드는 여기서 있으면 좋은 것이 아니라 수십 년과 인력 교체에 걸친 보증, 감사, 연속성을 위한 요건입니다. 목표는 의도를 전달하고, 실패에 저항하고, 검증할 수 있는 코드입니다. 그저 실행되는 코드로는 충분하지 않습니다.

핵심 원칙

  • 무엇보다 복잡성을 최소화하십시오. 대규모 구축의 주된 적은 아무도 온전히 이해할 수 없는 코드입니다.
  • 변경을 예상하십시오. 있을 법한 미래의 수정이 국소화되고 싸도록 구축하십시오.
  • 검증을 위해 구축하십시오. 테스트, 리뷰, 추론으로 정확성을 확인하기 쉬운 코드를 쓰십시오.
  • 의도적으로 재사용하십시오. 재발명하기보다 신뢰할 수 있는 기존 구성 요소 위에 구축하되, 잘못된 추상화에 결합되는 것은 피하십시오.
  • 표준을 따르십시오. 코드베이스 전반의 일관성은 모든 미래 변경의 인지 비용을 줄입니다.
  • 오류와 잘못된 상태를 명시적으로 처리하십시오. 실패 양상을 조용하지 않고 보이게 만드십시오.
  • 코드를 읽기 좋게 유지하십시오. 구축은 컴파일러보다 먼저 미래의 유지보수자와의 소통입니다.

권장 사항

복잡성 최소화를 주된 규율로 삼는다

본질적인 것과 우발적인 것 모두의 복잡성을 줄이는 것을 중심 목표로 삼으십시오. 작고 단일 목적의 함수와 모듈을 쓰십시오. 영리한 속임수보다 분명한 이름을 선호하십시오. 중첩을 얕게, 제어 흐름을 선형으로 유지하십시오. 한 코드를 이해하기 위해 시스템 전체를 머릿속에 담아야 하지 않도록 결정을 국소화하십시오. 복잡성은 큰 코드베이스를 바꾸기 느리고 건드리기 위험하게 만드는 것이므로, 모든 선택을 그것이 복잡성을 더하는지 덜어내는지로 저울질하십시오. 2.2장의 설계 원칙을 작은 규모에도 적용하십시오. 높은 응집도, 낮은 결합도, 분명한 관심사 분리는 아키텍처에서만큼 단일 함수에서도 중요합니다.

변경과 검증을 위해 구축한다

가장 올 법한 변경(새 비즈니스 규칙, 새 통합, 새 규제)을 앞서 생각하고, 변경이 국소적으로 머물도록 안정적인 인터페이스 뒤에 격리하십시오. 동시에 검증하기 쉬운 코드를 쓰십시오. 가능한 곳에서는 순수 함수(같은 입력은 항상 같은 출력을 내고 부수 효과가 없음), 최소한의 숨은 상태, 테스트가 대체할 수 있도록 명시적으로 만든 의존성입니다. 테스트하기 어려운 코드는 대개 이해하고 바꾸기 어려운 코드입니다. 테스트 용이성(2.4장)은 단지 QA의 관심사가 아니라 설계 신호입니다.

의도적으로 재사용하고 표준화한다

기초 로직을 다시 쓰기 전에 잘 유지되는 신뢰할 수 있는 라이브러리와 내부 구성 요소에 손을 뻗고, 분명한 인터페이스(2.3장)를 통해 사용하십시오. 진짜 두 번째 사용 사례가 있을 때만 재사용 가능한 구성 요소를 만드십시오. 너무 일찍 일반화하는 것 자체가 복잡성의 한 형태이기 때문입니다. 조직의 코딩 표준과 스타일(2.1장)을 일관되게 적용하고, 이상적으로는 자동 포매터와 린터로 시행해, 코드베이스 전체가 한 명의 신중한 작성자가 쓴 것처럼 읽히게 하십시오.

판단력을 갖추고 방어적 프로그래밍을 실천한다

신뢰 경계(외부 요청, 파일 및 네트워크 I/O, 사용자 입력)에서 입력을 검증하고, 그 경계를 넘는 모든 데이터는 증명되기 전까지 적대적인 것으로 다루십시오. 그러나 잘 테스트된 모듈 안에서는 모든 줄을 로직을 가리고 진짜 실패를 억누르는 중복 검사로 뒤덮지 마십시오. 규칙은 단순합니다. 경계에서 방어하고, 그 안에서는 신뢰하십시오. 올바른 프로그램에서는 절대 거짓이어서는 안 되는 불변식을 문서화하고 시행하는 데 단언을 쓰십시오. 런타임에 정당하게 일어날 수 있는 조건에는 예외와 오류 처리를 쓰십시오. 둘을 분리해 두십시오. 단언은 프로그래머의 가정을 지키고, 오류 처리는 예상되는 실패를 관리합니다.

오류를 명시적으로 처리하고 안전하게 실패한다

각 오류에 대해 무엇을 할지 의도적으로 정하십시오. 복구, 재시도, 전파, 빠르게 실패 중에서입니다. 예외를 조용히 삼키거나 반환된 오류를 무시하지 마십시오. 억눌린 실패는 나중에 수수께끼 같은 결함으로 돌아옵니다. 실패를 진단할 수 있도록 오류 메시지와 로그에 맥락을 유지하십시오. 안전 핵심 및 시민 핵심 시스템에서는 손상된 상태로 계속하는 대신 안전하고 알려진 상태로 실패하십시오. 오류 경로에도 행복한 경로만큼 생각을 쏟으십시오. 프로덕션에서는 오류 경로에서 신뢰를 얻거나 잃기 때문입니다.

구축 중에 품질을 내장한다

품질은 사후에 검사해서 넣는 것이 아니라 내장하는 것입니다. 코드와 함께 단위 테스트를 쓰고, 정적 분석과 린터를 지속적으로 실행하고, 추론할 수 있을 만큼 함수를 작게 유지하십시오. 주석이 무엇이 아니라 왜를 설명할 수 있도록 스스로 설명하는 이름과 구조를 쓰십시오. 코드를 살 만하게 유지하도록 진행하면서 리팩터링하십시오. 코드 리뷰(2.5장)는 사람의 안전망이지만, 품질의 대부분은 리뷰가 시작되기 전에 이미 있어야 합니다.

구축 도구를 고르고 표준화한다

도구 체인(컴파일러, 빌드 시스템, 포매터, 린터, 정적 분석기, 디버거, 의존성 관리자, IDE 설정)을 표준화해 모든 엔지니어가 일관되고 재현 가능한 환경에서 일하게 하십시오. 이 도구를 파이프라인에 연결해 품질 검사가 선택 사항이 아니게 하십시오. AI 지원 코딩 도구를 의도적으로 도입하고, 그 출력을 다른 모든 코드와 같은 표준, 리뷰, 테스트를 통과해야 하는 초안으로 다루십시오.

장단점

관행장점단점
적극적인 복잡성 최소화읽기 쉽고, 바꾸기 쉽고, 낮은 결함률느리게 느껴질 수 있음. 잘못 적용하면 과추상화 위험
광범위한 방어적 검사잘못된 상태를 일찍 잡음. 견고한 경계로직을 어지럽힘. 과하면 진짜 버그를 가릴 수 있음
불변식을 위한 단언가정을 문서화하고 시행일부 프로덕션 빌드에서는 비활성화됨. 오류 처리가 아님
라이브러리의 많은 재사용소유할 코드가 적음. 더 빠른 전달의존성 위험, 결합, 공급망 노출
엄격한 표준과 린팅획일적이고 마찰 낮은 코드베이스선행 설정. 개인에게는 경직되게 느껴질 수 있음
테스트 용이성을 위한 구축검증 가능하고 바꿀 수 있는 코드일부는 의식으로 보는 간접화가 늘 수 있음

구축의 핵심 트레이드오프는 단기 속도 대 장기 변경 가능성입니다. 지름길(오류 처리 건너뛰기, 복잡성 용인, 표준 무시)은 그 순간에는 더 빠르게 느껴지고, 시스템의 수명에 걸쳐서는 거의 항상 더 비쌉니다. 반대의 실패는 과설계입니다. 지나친 방어, 추측성 추상화, 아무도 필요로 하지 않는 일반성입니다. 숙련된 구축은 중간에 삽니다. 가능한 한 단순하게, 경계가 요구하는 만큼 방어적으로, 그 이상은 아닙니다.

팀과 논의할 질문

  1. “너무 복잡하다”의 공유된 구체적 정의는 무엇이며, 병합 전에 어디에서 시행합니까? “복잡성을 최소화하라”는 구축의 핵심 규율이지만 구호로는 모든 논쟁에서 마감에 집니다. 수백 명이 하나의 코드베이스에 쓰는 큰 팀에서 복잡성은 측정 가능해야 하므로, 실제로 행동할 신호에 합의하십시오. 함수 길이, 중첩 깊이, 순환 복잡도, 독자가 하나의 변경을 이해하려고 머릿속에 담아야 하는 것의 수입니다. 가장 심한 사례를 회의에 가져와 현재 리뷰가 그것을 잡았을지 물으십시오. 답은 파이프라인 관문이나 리뷰 체크리스트 항목이 되어야 합니다. 도구가 시행하는 임계값이 의지력이 시행하는 원칙보다 값지고, 다음 채용자가 아무도 안전하게 건드릴 수 없는 코드가 천천히 쌓이는 것을 면하게 해 주기 때문입니다.

  2. 프로덕션에서 우리의 오류 경로는 설계한 대로 동작하며, 마지막으로 의도적으로 하나를 실행해 본 것은 언제였습니까? 구축 조언은 오류 경로에도 행복한 경로만큼 생각을 쏟으라고 하지만, 오류 경로는 보통 가진 코드 중 가장 덜 테스트된 것이고, 시민 핵심이나 안전 핵심 시스템에서는 신뢰를 얻거나 잃는 곳입니다. 억눌린 예외나 무시된 반환 코드는 몇 주 뒤 수수께끼 같은 결함이 되며, “안전한 상태로 실패”는 그것이 일어나는 것을 본 적이 없다면 지킬 수 없는 약속입니다. 인시던트 이력을 가져오십시오. 과거 장애 중 몇 건이 삼켜진 오류나 테스트되지 않은 복구 경로로 거슬러 올라갔습니까? 행동은 실패를 의도적으로 테스트하는 것(거절된 카드, 타임아웃, 잘못된 입력을 주입)과, 모든 오류가 처리되거나, 맥락과 함께 로그에 남거나, 전파되고, 절대 조용히 버려지지 않을 것을 요구하는 것입니다.

  3. 코드베이스의 어느 부분이 테스트하기 어려우며, 그 어려움은 설계에 대해 무엇을 말해 줍니까? 테스트에 저항하는 코드는 거의 항상 상태를 숨기거나, 잘못된 의존성에 결합되거나, 너무 많은 일을 하는 코드이므로, 테스트 용이성은 QA의 사후 생각이 아니라 설계 신호입니다. 오래 사는 기업 시스템에서 이것이 중요한 이유는 오늘 테스트하기 고통스러운 모듈이 낯선 사람이 5년 뒤 바꾸기를 두려워할 모듈이기 때문입니다. 팀이 테스트 쓰기를 두려워하는 클래스나 서비스를 가져와 이유를 물으십시오. 상태가 숨어 있는가, 의존성을 대체할 수 없는가, 함수가 세 가지 일을 하는가? 답은 리팩터링을 순수 함수, 명시적 의존성, 작고 단일 목적의 단위 쪽으로 이끌어야 합니다. 코드를 검증 가능하게 만드는 일이 이해하기 쉽고 바꾸기 싸게 만드는 일과 같은 일이기 때문입니다.

  4. 외부 라이브러리를 재사용하는 때와 능력을 직접 구축하는 때는 언제이며, 우리가 지는 공급망 위험은 누가 소유합니까? 신뢰할 수 있는 라이브러리에 손을 뻗는 것은 기초 로직을 재발명하는 것보다 빠르지만, 추가하는 모든 의존성은 통제하지 못하고, 쉽게 감사할 수 없고, 침해되는 날 패치해야 하는 코드입니다. 큰 팀에서 위험은 백 명의 엔지니어가 각자 자기 전이 의존성을 끌어와 코드베이스가 실제로 무엇을 실행하는지 아무도 말할 수 없게 되는 것입니다. 의존성 목록을 가져와 세 가지를 구체적으로 물으십시오. 유지되지 않는 라이브러리가 몇 개인지, 알려진 취약점을 지닌 것이 몇 개인지, 직접 소유할 만큼 단순한 로직을 감싼 것이 몇 개인지입니다. 상충하는 고려는 실제입니다. 자체 암호나 날짜 처리를 쓰는 것은 거의 항상 실전에서 검증된 라이브러리보다 나쁘므로, 목표는 전면적 회피가 아니라 의도적인 재사용 정책입니다. 기업과 정부 환경에서는 조달과 라이선스 컴플라이언스 측면을 더하십시오. 검증되지 않은 의존성은 여러분의 의무와 양립할 수 없는 라이선스나 어떤 감사자도 받아들이지 않을 출처를 지닐 수 있기 때문입니다.

  5. AI가 생성한 코드를 사람이 쓴 코드와 같은 구축 표준에 어떻게 두며, 중요할 때 둘을 구분할 수 있습니까? AI 코딩 어시스턴트는 그럴듯한 초안을 빠르게 만들고, 유혹은 컴파일되고 관용적으로 보인다는 이유로 그 출력을 완성된 것으로 다루는 것입니다. 이 장의 규칙은 생성된 코드가 다른 모든 것과 같은 리뷰, 테스트, 표준을 통과한다는 것이며, 큰 팀은 이 규칙을 열망이 아닌 운영 가능한 것으로 만들어야 합니다. 최근 출시된 AI 지원 변경의 예를 가져와, 각각이 테스트를 지녔는지, 정적 분석을 통과했는지, 제출한 사람이 진정으로 이해했는지, 아니면 신뢰로 통과되었는지 물으십시오. 상충하는 압력은 속도입니다. 이 어시스턴트는 정말 생산적이고, 모든 제안을 느리게 만들면 이점을 버리는 셈이기 때문입니다. 규제와 정부 맥락에서는 출처와 책임성 측면을 더하십시오. 코드 한 줄에 누가 책임지는지, 생성된 조각에 답할 수 없는 라이선스나 저작권 문제가 있는지 증명해야 할 수 있기 때문입니다.

  6. 구축 도구 체인이 실제로 표준화되고 파이프라인에서 시행되고 있습니까, 아니면 개인들이 여전히 호환되지 않는 설정에서 일합니까? 포매터, 린터, 정적 분석기, 빌드 시스템, 의존성 관리자의 공유 도구 체인은 엔지니어가 낯선 서비스를 자신 있게 오가게 해 줍니다. 코드가 한 목소리로 읽히고 검사가 어디서나 동일하기 때문입니다. 표류하면 모든 팀이 자기 설정을 재발명하고, 리뷰 시간이 스타일 논쟁에 쓰이고, 한 팀의 분석기가 잡았을 결함이 다른 팀에서는 빠져나갑니다. 모든 커밋에서 표준 검사를 실행하지 않는 저장소의 목록을 가져와 각각이 왜 빠졌는지 물으십시오. 긴장은 단일 의무 설정이 진정으로 다른 필요를 가진 팀에게는 경직되게 느껴질 수 있다는 점이므로, 어디에서 획일성이 마찰을 감수할 가치가 있고 어디에서 문서화된 예외가 괜찮은지 정하십시오. 큰 기업이나 공공 기관에서는 이를 재현 가능성과 감사에 연결하십시오. 통제된 도구 체인에서 바이트 단위로 재현할 수 없는 빌드는 몇 년 뒤 평가자에게 방어할 수 없는 빌드이기 때문입니다.

분야별 관점

스타트업. 속도가 이기니, 첫날 공유 포매터와 린터를 갖추고, 하나의 외부 경계에서 입력을 검증하고, 내부 코드는 모든 줄에서 방어적이지 않게 깨끗하게 유지하십시오. 추측성 추상화와 무거운 프로세스는 건너뛰십시오. 엔지니어가 두세 명이면 팀 전체가 코드베이스를 머릿속에 담고 있으며, 진짜 위험은 그 공유된 기억보다 오래 사는 복잡성입니다. 기초적인 것은 신뢰할 수 있는 라이브러리에 의지해, 잘 소유할 수 있는 만큼만 코드를 쓰십시오.

소기업. 전담 빌드 엔지니어도 빠듯한 예산도 있으니, 기존 도구가 공짜로 시행하는 관례를 선호하십시오. 언어와 함께 오는 포매터와 린터, 합리적인 기본값, 모두가 기억할 수 있는 소수의 규칙입니다. 유지할 인력이 없는 인프라를 만들기보다 잘 유지되는 라이브러리를 사거나 채택하십시오. 제한된 규율을 소홀히 하면 가장 아픈 두 가지에 쓰십시오. 경계에서 입력을 검증하는 것과 오류를 조용히 삼키지 않는 것입니다.

대기업. 수백 명의 엔지니어가 공유 코드에 쓰므로 우선순위는 획일성과 시행입니다. 파이프라인에 연결된 표준 도구 체인, 정적 분석 관문, 어디서나 적용되는 경계 검증 규칙으로 사람들이 서비스 사이를 자신 있게 오가게 하십시오. 의존성과 공급망 위험을 팀별 즉흥이 아니라 다스려지는 프로세스로 관리하고, 모든 팀에 걸쳐 성립해야 하는 도메인 불변식을 부호화하는 데 단언을 쓰십시오. 구축 표준을 수십 년과 인력 교체에 걸쳐 코드베이스를 살 만하게 유지하는 기반으로 다루십시오.

정부. 오래 살고 시민에게 핵심적인 시스템은 규율 있는 구축을 보증과 책임성의 문제로 만듭니다. 입법 같은 변하는 규칙을 안정적인 인터페이스 뒤에 격리해 변경이 국소적으로 머물고 요구사항까지 추적되게 하고, 손상된 상태로 계속하지 말고 안전하고 알려진 상태로 실패하고, 모든 모듈에 감사 증거를 겸하는 테스트를 함께 내보내십시오. 조달과 투명성 의무는 도구 체인, 의존성, 오류 처리가 여러 해 뒤에 도착한 공무원이나 외부 감사자가 코드가 올바름을 검증할 수 있을 만큼 잘 문서화되어야 한다는 뜻입니다.

사례

스타트업. 세 명 규모의 스타트업은 첫날 공유 포매터와 린터를 설정해 모든 커밋에서 실행하므로, 계약자를 추가해도 코드베이스가 한 목소리로 읽힙니다. API 경계에서 입력을 검증하고 외부의 모든 것을 적대적으로 다루지만, 내부 로직은 중복 검사로 뒤덮는 대신 깨끗하게 유지합니다. 결제 웹훅이 실패하기 시작했을 때, 어떤 예외도 조용히 삼켜진 적이 없고 오류 메시지가 원인을 곧장 가리킬 만큼 맥락을 담고 있어서 수정이 빠릅니다. 전체 설정에 오후 한나절이 들었고, 다음 채용자의 첫 주를 비참하게 만들었을 복잡성의 느린 축적을 면하게 해 주었습니다.

대기업. 한 글로벌 결제 회사는 수백 명의 엔지니어에 걸쳐 공유 도구 체인을 시행합니다. 모든 커밋에서의 자동 서식과 린팅, 파이프라인의 정적 분석 관문, 모든 외부 입력이 서비스 경계에서 검증되어야 한다는 규칙입니다. 도메인 로직은 “원장 항목은 항상 균형이 맞는다” 같은 불변식을 시행하는 데 단언을 쓰고, 거절된 카드 같은 런타임 조건은 명시적이고 로그에 남는 결과로 처리됩니다. 표준이 획일적이고 오류가 조용히 삼켜지지 않기 때문에, 엔지니어는 낯선 서비스를 자신 있게 오가고 프로덕션 인시던트는 로그에서 곧바로 진단할 수 있습니다.

정부. 한 국가 세무 기관이 변하는 법령 아래 수십 년 운영될 것으로 예상되는 장수 평가 시스템을 구축합니다. 구축은 각 세금 규칙을 안정적인 인터페이스 뒤에 격리하므로, 연간 입법 변경이 국소적으로 머물고 요구사항(2.8장)까지 추적됩니다. 방어적 검증이 모든 시민 대면 입력을 지킵니다. 오류 경로는 잘못된 평가를 조용히 발행하지 않는 안전한 상태로 실패합니다. 모든 모듈은 감사 증거로서의 단위 테스트와 함께 출시됩니다. 구축이 표준화되고 잘 문서화되어 있어서, 새 공무원들이 오래전에 떠난 전임자가 쓴 코드를 안전하게 유지할 수 있습니다.

비즈니스 사례: 동기, ROI, TCO

규율 있는 구축의 수익은 소프트웨어를 싸고 안전하게 바꿀 수 있는 지속적인 능력이며, 시스템 총소유비용의 대부분이 여기서 결정됩니다. 소프트웨어 경제학 연구는 시스템 수명 비용의 대부분이 유지보수이고, 유지보수 비용은 코드가 얼마나 이해하기 쉽고 바꾸기 쉬운지에 지배됨을 일관되게 보여 줍니다. 복잡성을 최소화하고, 오류를 명시적으로 처리하고, 표준을 따르는 것은 모든 미래 변경과 모든 프로덕션 인시던트의 비용을 직접 낮춥니다.

도입 비용은 소소하고 대부분 선행입니다. 표준을 정하고, 린터와 분석기를 연결하고, 검증 가능하고 방어적인 코드를 쓰는 습관을 쌓는 것입니다. 반면 방치의 비용은 누적됩니다. 복잡성은 바꾸기 느리고 건드리기 위험한 코드로 쌓입니다. 조용한 오류는 비싼 프로덕션 인시던트가 됩니다. 일관되지 않은 스타일은 모든 리뷰와 모든 온보딩의 노력을 곱합니다. 리더십을 설득하려면 구축 품질을 변경 실패율, 평균 복구 시간, 결함 유출률, 온보딩 시간에 연결하십시오. 이 모두를 구축 규율이 직접 개선합니다.

안티패턴과 함정

  • 복잡성 잠식: 아무도 이해하지 못할 때까지 영리하고, 깊이 중첩되고, 퍼져 나가는 코드를 쌓는 것.
  • 조용한 오류 삼키기: 빈 catch 블록과 무시된 반환 코드가 실패를 미래의 수수께끼로 바꿉니다.
  • 방어적 프로그래밍 과잉: 로직을 묻고 진짜 결함을 가리는 곳곳의 중복 검사.
  • 단언과 오류 처리의 혼동: 런타임 조건에 단언을, 프로그래머의 불변식에 예외를 쓰는 것.
  • 복사-붙여넣기 구축: 재사용 대신 로직을 복제해 수정이 여러 곳에서 이루어져야 하는 것.
  • 추측성 일반화: 오지 않을 필요를 위한 추상화와 설정 가능성을 구축하는 것.
  • 표준 무시: 모든 엔지니어가 자기 방식으로 코딩해 코드베이스 전반의 인지 부하를 곱하는 것.
  • 테스트되지 않은 구축: 테스트 없이 코드를 쓰고 검증을 오지 않는 단계로 미루는 것.

성숙도 모델

  • 1단계(시작): 구축이 그때그때 이루어지고 반응적입니다. 복잡성과 오류 처리는 개인마다 다르고, 표준이 거의 없으며, 조용한 실패가 흔합니다.
  • 2단계(발전): 코딩 표준, 포매터, 린터가 있고 기본적인 오류 처리와 단위 테스트가 기대되지만, 관행이 일관되지 않고 각 팀이 다르게 적용합니다.
  • 3단계(표준화): 복잡성 최소화, 경계 검증, 명시적 오류 처리, 테스트 용이성이 문서화되어 파이프라인과 리뷰에서 조직 전체에 시행되므로, 코드베이스 전체가 한 명의 신중한 작성자가 쓴 것처럼 읽힙니다.
  • 4단계(관리): 구축 품질이 기준선에 대해 측정됩니다. 팀은 순환 복잡도, 결함 유출률, 변경 실패율, 오류 경로 테스트 커버리지, 코드 리뷰 발견을 추적하고, 의견이 아닌 추세에 따라 행동합니다.
  • 5단계(오케스트레이션): 구축이 지속적으로 개선되고 조직 전체에 통합됩니다. 방어 패턴, 표준, 지표가 리팩터링과 도구에 되먹임되고, AI 지원 도구는 같은 품질 관문 아래 돌아가며, 관행은 언어, 규제, 위험이 변함에 따라 적응합니다.

논의를 위한 아이디어

  • 코드베이스에서 우발적 복잡성이 가장 많이 쌓이는 곳은 어디이며, 어떤 구축 습관이 그것을 만듭니까?
  • 입력을 검증할 곳과 신뢰할 곳에 대한 팀의 실제 규칙은 무엇입니까?
  • 엔지니어들이 단언과 오류 처리를 구분하며, 그 구분이 일관됩니까?
  • 품질의 얼마가 구축 중에 내장되고, 얼마가 나중에 리뷰나 테스트에서 잡힙니까?
  • 공급망 위험을 감안할 때 라이브러리를 재사용할지 구축할지 어떻게 결정합니까?
  • AI가 생성한 코드를 사람이 쓴 코드와 같은 구축 표준에 어떻게 두어야 합니까?

핵심 요점

  • 구축은 설계가 유지보수 가능한 코드가 되는 곳입니다. 복잡성 최소화가 그 중심 규율입니다.
  • 변경과 검증을 위해 구축하십시오. 테스트할 수 있고 바꿀 수 있는 코드는 이해할 수 있는 코드입니다.
  • 신뢰 경계에서 방어하고 그 안에서는 신뢰하되, 오류를 절대 조용히 삼키지 마십시오.
  • 불변식에는 단언을, 예상되는 런타임 조건에는 오류 처리를 쓰십시오. 혼동하지 마십시오.
  • 도구와 스타일을 표준화하고, 의도적으로 재사용하고, 사후에 검사하는 대신 품질을 내장하십시오.

참고 문헌과 더 읽을거리

  • IEEE Computer Society, SWEBOK Guide (Guide to the Software Engineering Body of Knowledge), Software Construction knowledge area
  • Steve McConnell, Code Complete: A Practical Handbook of Software Construction
  • Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship
  • Andrew Hunt and David Thomas, The Pragmatic Programmer
  • Martin Fowler, Refactoring: Improving the Design of Existing Code
  • John Ousterhout, A Philosophy of Software Design