6장 기술 품질의 관리

2023.03.17

  • 대부분 낮은 기술 품질은 위기가 아니다. 얼마든지 발생할 수 있는, 지극히 정상적인 상태다.
  • 보통 엔지니어는 품질에 대해서 합리적인 결정을 내리며, 성공적인 기업은 사업을 확장하거나 사업 방향을 돌리거나 기업을 대상으로 시장을 확대해 나가면서 천천히 품질 기준을 높여간다
  • 잘 운영되고 성공적으로 사업을 수행하는 기업이라면 이전에 내렸던 기술적 결정의 상당 부분이 현재의 품질 기준에 맞지 않을 것이다.
  • 현재 기술 품질 수준과 목표 수준의 차이를 줄이는 것은 실패가 아니라 효율적인 엔지니어링 리더십의 기본이자 반복적으로 수행해야 할 과제다.

문제점

  • 엔지니어링 리더로서 여러분의 목표는 핵심 비즈니스에 에너지를 집중하면서도 적절한 수준의 기술 품질을 유지하는 것이다.
  • 여러분은 반드시 여러 기간에 걸쳐 품질의 균형을 맞춰야 하는데 이 과정에서 각 기간의 요구사항이 상충되기도 한다.
  • 여러분이 속한 회사의 기술 품질 수준이 시간이 지나면서 높아지는 것처럼 기술 품질을 관리하기 위한 방법도 그에 맞춰 개선될 것이다.
  • 기술 품질은 장기적인 게임이다. 이 게임에 승리 따위는 없으며 오로지 배우고 계속 게임에 참여할 기회를 얻는 것뿐이다.

계단 오르기

  • 팀과 조직을 위한 적절한 품질 개선을 생각한다면 가장 부담이 적은 솔루션부터 도입한 후 이 해결책이 성장의 압박을 못 이겨 더 이상 작동하지 않을 때만 더 규모가 큰 솔루션으로 이전하는 것이 가장 효과적이다. ****
  • 규모가 큰 솔루션은 조직의 규모가 크면 더 효과적이지만 실행하기는 훨씬 더 어렵다.
  • 그러므로 빠르게 적용할 수 있는 것부터 먼저 시작하자!

문제 지점

  • 품질 문제를 다루면서 가장 먼저 나타나는 행동 경향은 절차상 실패를 찾아냈을 때 절차적으로 해결하려고 하는 경우다.
  • 절차를 도입한다는 것은 사람이 일하는 방법을 바꾼다는 것이므로 이 점을 가벼이 여겨서는 안 된다.
  • 절차를 개선하기보다는 성능 엔지니어의 마음 가짐을 갖는 것부터 시작해야 한다.
  • 당면한 문제를 측정하고 대부분의 문제가 발생하는 부분을 찾아 그 부분에 정확히 집중해야 한다.
  • 테스트가 제대로 이뤄지지 않은 상태에서 배포한 경우를 생각해보자. 배포한 엔지니어에게 테스트하는 습관을 바꾸라고 직접 피드백을 주는 것이 좋을 수도 있다.

권장 사례

  • 권장 사례를 도입하려면 조직과 경영진이 그만큼 성숙해야 하며 필요한 성숙도를 갖추려면 시간이 필요하다.
  • 새로운 사례를 도입할 때 적절한 절차는 지시에 의해 만들어지는 것이 아니라 진화를 통해 만들어진다.
  • 다른 기업이 어떻게 유사한 사례를 도입했는지 연구하고, 여러분이 의도하는 접근 방법을 문서화한 후 몇몇 팀을 선택해 그 사례를 실습해보고, 필요한 부분을 다듬고, 문제 지점에 기초해 문서를 개선한 후에나 실질적인 도입이 가능하다. 이를 너무 급하게 진행하면 결국은 실패한다.
  • 문제 지점을 수정하는 방법에서 권장 사례를 도입하는 방법으로 전환하는 것은 수정해야 할 문제 지점이 곤란할 정도로 많아질 때 일어난다.
  • 그 후 권장 사례에서 지렛점으로 전환하는 것은 도입 중인 권장 사례가 제대로 동작하기도 전에 새로운 권장 사례를 도입하고 싶을 때 일어난다.

지렛점

  • 소프트웨어가 그동안 어떻게 변화해 왔는지 살펴보면, 전체적인 품질 문제를 방지하고 향후의 품질 개선 비용을 줄임으로써 조금만 투자하면 시간이 지나도 품질을 유지할 수 있는 부분이 있다.
  • 필자는 이런 부분을 지렛점이라고 부른다.
  • 그중에서도 효과가 큰 세 가지는 인터페이스(interface), 상태가 있는(stateful) 시스템, 데이터 모델이다.
  • 인터페이스
    • 인터페이스는 시스템 간 계약(contract)이다.
    • 효율적인 인터페이스는 클라이언트와 실제 구현을 분리한다.
    • 견고한 인터페이스는 기본적인 복잡도를 모두 외부로 노출하지만 부수적인 복잡도는 노출하지 않는다.
    • 잘 설계한 인터페이스는 직관적이기 때문에 쉽게 사용할 수 있다.
  • 상태
    • 어떤 시스템에서든 가장 바꾸기 어려운 부분이다.
    • 상태가 있는 시스템은 또 다른 중요한 지렛점이다.
    • 상태는 다른 시스템보다 더 빠 게 복잡해지며 나중에 개선할 때도 상대적으로 비용이 많이 들어가는 경 향이 있다.
  • 데이터 모델
    • 데이터 모델은 인터페이스와 상태의 교집합이며 상태가 있는 시스템의 능력을 애플리케이션이 적절하다고 생각하는 수준으로 떨어뜨린다.
    • 좋은 데이터 모델은 강직해서 정말로 지원해야 할 것만 노출하며 유효하지 않은 상태를 표현하지 못하도록 구현되어 있다.

기술 요소

  • 효율적인 조직은 조직이 공유하는 비전을 이루기 위해 최대한 많이 집중한다.
  • 모든 기술적 결정 사항을 그리드에 벡터 형태로 나열할 때 더 많은 벡터가 같은 방향을 가리킬수록 시간이 지나면서 더 많은 것을 이룰 수 있다.
  • 기술적 방향을 유지하기 위한 확시한 방법은 아키텍트 직책을 가진 사람에게 관련된 모든 결정을 맡기는 것이다.
    • 이 방법은 잘 먹히기는 하지만 규모가 커지면 문제가 된다.
    • 실제 절차에서 실제 코드를 작성하는 실질적인 업무를 하다 보면 아키텍트의 의사결정 품질이 점점 떨어지기 때문이다.
  • 기술 요소의 방향을 유지하기 위한 기본 도구
    • 직접적인 피드백을 제공하자.
      • 보통 직원들의 방향성이 일치하지 않으면 가장 먼저 절차의 변경을 시도한다.
      • 그러지 말고 방향성이 어긋나는 직원에게 개별적으로 피드백을 직접 주는것부터 시도해보자.
    • 기술스펙부터 전략과 비전까지 엔지니어링 전략을 재정의하자.
    • 접근 방법을 워크플로와 도구로 캡슐화하자.
      • 명확한 비전을 문서화하는 것은 유용한 일이지만 일부 직원은 여러분이 작성한 문서를 읽지 않을 것이다.
      • 신중히 고른 도구는 교육과 문서보다 훨씬 나은 습관을 기르도록 유도하는 워크플로를 만들어낸다.
    • 신규 입사자는 온보딩 기간에 교육하자.
    • 콘웨이의 법칙(Conway’s Law)을 활용하자.
      • 조직이 구현하는 소프트웨어가 그 조직의 구조를 반영한다는 법칙.
      • 조직의 설계가 효율적이라면 그만큼의 품질을 보장하기도 한다.
    • 아키텍처 리뷰, 투자 전략, 새로운 도구를 도입하는 구조적 절차를 이용해 기술적 변화를 구조화하자.

기술 품질의 측정

  • 소프트웨어 엔지니어링 분야에서 뭔가를 측정하려는 욕구는 현재 측정 방식보다 훨씬 앞서 있다.
  • 변경의 효율성을 절차적으로 측정할 수 있는 기법이 몇 가지 있다.
    • 풀 리퀘스트의 크기가 작을수록 품질이 높다면 풀 리퀘스트마다 변경된 파일의 수를 측정할 수 있다.
    • 크기가 큰 파일은 보통 확장이 어렵다는 점을 감안해 파일당 코드 라인 수를 측정할 수도 있다.
  • 위 방법은 코드 품질을 위한 최선의 프록시 측정 지표다.
  • 품질에 대해 더욱 상세하게 정의할수록 기반 코드를 측정하는 것이 더 유용해지며, 작업 중인 부분의 품질을 향상시키려는 사람이 더 유익하게 사용할 수 있다.
  • 품질 정의에 포함할 몇 가지 요소
    • 정적 타입을 사용하는 코드는 몇 퍼센트인가?
    • 테스트에 관여한 파일은 몇 개인가?
    • 기반 코드의 테스트 커버리지는 어느 정도인가?
    • 모듈의 공개 인터페이스는 얼마나 제한적으로 설계됐는가?
    • 몇 퍼센트의 파일이 적절한 HTTP 라이브러리를 사용했는가?
    • 엔드포인트(endpoint)는 콜드 스타트 후 500밀리초 내에 응답하는가?
    • 읽기 후 쓰기(read-alter-write) 같은 위험한 동작을 수행하는 함수는 몇 개인가? 또는 주 데이터베이스에 불필요한 읽기 작업을 수행하는 함수는 몇 개인가?
    • 단일 트랜잭션 내에서 모든 상태 변경을 수행하는 엔드포인트는 몇 개인가?
    • 작은 단위 잠금(low-granularity lock)을 획득하는 함수는 몇 개인가?
    • 폴 리퀘스트 절반 이상에서 변경이 발생하는 파일은 몇 개인가?
  • 중요한 것은 간결하면서도 측정 가능한 품질을 정의하는 것이다.
  • 품질을 정의했다면 지금부터 계측(instrumentation)이 어려워질 수 있다.
  • 계측은 유용한 지표에 대한 요구 사항이다.
  • 계측 복잡도는 이 기법을 실질적으로 적용하는 데 가장 어려운 부분이지만 이를 잘 넘긴다면 상당히 유용하다.

기술 품질 팀

  • 기술 품질 팀은 기반 코드의 품질 관리를 전담하는 소프트웨어 엔지니어링 팀이다.
  • 이 팀은 품질 보증팀과는 다르다. 기술 품질 팀은 워크플로부터 테스트의 빌드와 인터페이스 설계까지 더 많은 역할을 담당한다.
  • 기술 품질 팀을 성공적으로 구축하고 운영하기 위한 몇 가지 원칙
    • 직감보다는 지표를 신뢰하자.
      • 모든 프로젝트를 측정할 수 있는 방법을 마련해야 한다.
      • 지표를 활용하면 정직하게 문제를 해결할 수 있다.
    • 직감을 새롭게 유지하자.
      • 코드와 절차는 시간이 지나면서 바뀌며 제품의 기능이 구현에서 멀어지면 여러분의 직감 역시 한 주가 다르게 무디어진다.
    • 사용자의 말에 귀 기울이고 사용자에게 배우자.
      • 가장 뛰어난 사람들은 사용자가 어떤 것을 하려는지 이해하고 구현상 제약보다 사용자의 수요를 더 우선적으로 고려한다.
      • 도구가 가진 원천 능력보다는 도구의 도입 용이성과 사용성이 훨씬 더 중요하다.
    • 더 적은일을 더 잘하자.
      • 전체 엔지니어링 조직을 위한 도구나 워크플로를 구축할 때 일이 제대로 되면 전체 조직의 속도가 개선될 것이다.
    • 영향을 묻어두지 말자.
      • 중앙식 품질 팀과 그 팀에게 지원받는 다른 팀 간에는 기본적인 긴장 상태가 존재한다.
      • 중앙식 품질 팀은 최적의 방법을 선호하지만 이 방법이 비정형 도메인이나 워크로드를 담당하는 팀에 큰 영향을 미치기 때문이다.

품질 프로그램

  • 품질 프로그램은 컴퓨터 코드가 아니라 조직 전체의 기술적 품질을 관리하는 전담 팀이 이끄는 계획을 말한다.
  • 품질 프로그램은 조직의 소프트웨어 품질 목표를 달성하기 위한 광범위한 업무를 수행한다.
  • 조직적 프로그램을 운영하는 핵심 방법
    • 프로그램 스폰서를 찾자.
      • 영향력이 있는 스폰서가 없이는 조직의 행동을 바꿀 수 없다.
      • 조직은 현재의 제약 상황에서 최적화된 방법이기 때문에 현재의 행동 양식을 가지고 있으며 힘있는 누군가의 지지 없이는 이런 제약을 바꿀 수 없다.
    • 지속 가능하며 재생산 가능한 지표를 만들자.
      • 프로그램 운영자가 일주일에 4시간 이상 직접 손으로 데이터셋을 관리하는 것은 보편적인 일이다.
      • 하지만 이 방법은 제대로 동작하지 않는다. 데이터에 구멍이 생길 것이며 이 데이터를 나중에 자동화와 통합하는 것도 불가능하다.
    • 영향을 받는 모든 팀에 대한 프로그램의 목표와 그 목표를 완수하기 위한 명확한 경로를 정의하자.
      • 영향을 받는 모든 팀을 위해 프로그램은 특정한 목표를 정의해야 한다.
      • 각 팀이 각자의 몫을 어떻게 완수할 수 있는지 명확한 방향을 제시하지 않고 다른 팀이 참여하기 프로그램이 너무나 많다.
      • 프로그램 소유자는 관련 분야의 전문가이면서 모든 팀이 독립적으로 발전할 수 있는 여러분의 전략을 무시하지 않아야 한다.
    • 팀이 목표를 이룰 수 있도록 지원하는 도구와 문서를 구현하자.
      • 각 팀이 프로그램의 목표를 달성하기 위해 가야할 명확한 경로를 정의했다면 변화하기 위해 팀을 어떻게 도울 수 있는지 방법을 찾아야 한다.
      • 어떻게 해야 하는지 보여주는 '특별한 예시'를 제공하거나 코드의 어려운 부분을 새로운 패턴으로 리터링한 예제 풀 리스트를 보여줄 수도 있다.
      • 모든 팀이 진행 중인 문제 영역을 깊이 이해하지 않아도 되도록 최대한 많은 것을 지원해야 한다.
    • 목표 대시보드를 만들고 널리 공유하자.
      • 프로그램 목표를 각 팀에게 설명했다면 현재 각 팀의 목표 상태를 이해할 수 있도록 대시보드를 제공하고 팀의 진척 상황을 보강할 수 있는 피드백을 제공하자.
      • 최상의 대시보드는 각 팀의 작업에 대한 점수판과 더불어 다음으로 어떤 일에 집중해야 하는지 그 방향을 보여줄 수 있는 것이어야 한다.
    • 목표에 뒤쳐진 이들에게는 프로그래밍적으로 눈치를 주자.
      • 사람들은 바쁘기 때문에 프로그램의 목표를 달성하는 것을 항상 최우선으로 하지 않는다.
      • 이럴 때는 눈치를 줘서 팀이 프로그램 목적에 달성하기 위해 수행해야 할 다음 과제에 주목하게끔 할 수 있다. 하지만 주목은 매우 희소한 자원임을 기억하자.
    • 프로그램 상태를 스폰서와 정기적으로 리뷰하자.
      • 프로그램은 본질적으로 팀의 목표에 부합하지 않는 조직적 우선순위를 토대로 진행된다.
      • 전체 진행 상황을 스폰서와 리뷰하고 팀이 프로그램 작업을 우선적으로 수행할 수 있도록 하는 것이 중요하다.
  • 많은 프로그램이 수포로 돌아 가는 이유 세 가지.
    • 프로그램을 순전히 절차적 관점에서 운영하고 실제로 달성하려는 것에 대해 현실적으로 동떨어지게 운영하는 경우.
    • 프로그램을 순전히 기술적 관점에서 운영하고 이루려는 목적을 위한 필수 단계를 생략하거나 동기를 부여하려던 다른 직원의 의견을 듣지않는 경우.
    • 절차 및 기술적 관점을 혼자서 모두 감당하려 하는 경우. 절대 혼자서는 할 수 없다!

작게 시작하고 천천히 추가하자

  • 기술 품질을 관리하는 데 어려움을 겪고 있다면 일단 작은 것부터 시작하고 정상 궤도에 올라설 때까지 반복하자.
  • 시스템 과 상호의존성이 복잡하면 빨리 진행하라는 것은 그저 여론에 불과할 뿐이다.
  • 천천히 진행하는 편이 작업을 올바르게 완료할 수 있는 체계적인 방법이다.