제품 표면의 부채에 대한 고찰

저희는 문제를 해결하고 궁극적으로 가치를 창출하기 위해 소프트웨어를 구축합니다. 그렇게 하면서, 저희는 숙고해야 할 새로운 것을 만들어냅니다. 이는 진화하고 더욱 복잡해지는 시스템입니다. 이를 관리하고 변경하려면 이해가 필요합니다. 기능이 늘어남에 따라, 더 많은 지식이 필요하게 될 것입니다.

종종 팀은 고객에게 유용한 소프트웨어를 제공하면서 해결해야 할 추가적인 문제들을 발견합니다. 더 많은 문제는 고객에게 더 많은 가치를 제공하고 궁극적으로 조직에 더 많은 가치를 창출할 기회입니다.

반대로, 조직이 더 큰 가치를 제공하고자 할 때는 의도적으로 제품 표면을 관리하여 자산으로 유지하고 부채가 되지 않도록 해야 합니다. 이는 올바른 신호를 중요시하고 올바른 행동에 인센티브를 제공함으로써 제품 조직의 지속 가능성을 유지하기 위한 의도적인 노력을 기울이는 것을 의미합니다.

제품 표면 정의

저는 제품 표면(Product Surface)이라는 용어를 사용했으므로, 제 의미를 명확히 밝히겠습니다. 저는 이 개념을 사이버 보안에서 가져왔는데, 사이버 보안에서는 공격자가 시스템에 대한 무단 접근을 얻기 위해 악용할 수 있는 모든 진입점을 지칭하기 위해 공격 표면이라는 말을 흔히 사용합니다. 보안 팀이 공격 표면을 신중하게 관리해야 하는 것처럼, 제품 팀도 제품 표면을 관리해야 합니다.

마찬가지로, 저는 제품 표면을 최종 제품을 구성하는 최종 사용자에게 노출된 모든 기능 집합을 지칭하기 위해 사용합니다. 표면이 클수록 잠재적 부채가 커집니다. 더 많은 기능은 버그가 발생할 수 있는 더 많은 위치, 새로운 기능을 설계할 때 고려해야 할 더 많은 비즈니스 로직, 회귀가 발생할 가능성이 더 높다는 것을 의미합니다.

사이버 보안에서 공격 표면이 더 크다고 해서 자동으로 보안이 더 나빠지는 것은 아니지만, 방어하고 감시해야 할 영역이 더 많다는 것을 의미합니다. 마찬가지로, 제품 표면이 더 크다고 해서 본질적으로 문제가 있는 것은 아니지만, 효과적으로 유지 관리하려면 비례적으로 더 많은 조직적 자원이 필요합니다.

보안 팀은 또한 모든 새로운 기능이 잠재적으로 공격 표면을 확장한다는 것을 알고 있습니다. 그들은 개발 팀과 긴밀히 협력하여 기능을 추가하기 전에 보안 영향을 평가합니다.

제품 팀에게도 유사한 협업이 필요합니다. 그들은 모든 새로운 기능을 즉각적인 가치뿐만 아니라 전체 제품 표면을 효과적이고 지속 가능하게 유지하고 발전시키는 능력에 어떤 영향을 미치는지 평가해야 합니다.

자산-부채 스펙트럼

소프트웨어가 자산이라기보다는 부채라고 이야기하는 글이 많이 있습니다. 그들은 대개 소프트웨어 유지 관리의 부담과 그 부담을 상쇄하기 위해 창출해야 하는 가치에 초점을 맞춥니다.

저에게 있어, 그것은 대차 대조표의 항목으로서 소프트웨어의 직접적인 비용에 대한 것만이 아닙니다. 더 많은 코드는 더 많은 테스트를 필요로 하고, 버그 및 오류에 노출되는 표면을 증가시키며, 빌드 시간을 늘리고, 본질적으로 배포 시간을 늘리며, 구현되는 모든 새로운 기능과 함께 늘어나는 인지적 부담을 추가합니다.

새로운 코드는 가치를 창출할 때 가치가 있습니다. 동시에, (더 이상?) 가치를 창출하지 않는 코드는 부채로 바뀝니다. 가치 창출은 특정 상황에 따라 다른 의미를 가질 수 있으므로, 정의는 여러분에게 맡기겠습니다. 제가 강조하고 싶은 것은 팀이 전체 제품 표면이 생산하고 있는 가치를 지속적으로 평가해야 한다는 것입니다.

조직의 수명 주기 동안 구축하는 소프트웨어의 다양한 부분은 부채와 자산 상태 사이의 스펙트럼에서 유동적으로 변동할 것입니다. 현재 상태를 평가하고 언제 제거해야 할지 결정하는 것은 팀의 부채입니다.

부채/자산 스펙트럼

여러분의 팀이 2020년에 인기 있는 third-party 서비스와의 맞춤형 통합을 구축했다고 상상해 보십시오. 당시에는 많은 고객이 요청했기 때문에 이 기능은 가치가 있었습니다. 그러나 3년 후, 이 통합은 다음과 같은 경우에 부채가 됩니다.

  • 해당 third-party 서비스가 여러분의 integration이 의존하는 기존 API를 제거했을 때
  • 이제 기존 고객을 위해 기존 integration을 유지 관리하고 업데이트된 API에 대한 새로운 integration을 구축해야 할 때
  • 팀이 여전히 기존 integration을 사용하는 소수의 사용자에게만 영향을 미치는 edge case를 디버깅하는 데 상당한 시간을 할애할 때
  • 개발자가 기존 및 새로운 integration 패턴을 모두 이해해야 하므로 인지 부하가 증가할 때

자산이 될 것이라고 생각했던 것이 관리하기 더 어려운 제품 표면으로 바뀌었습니다. 더 많은 테스트는 빌드 및 배포 파이프라인 시간에 영향을 미칠 것입니다. 새로운 기능을 유지 관리하고 전체와 계속 어울리도록 해야 합니다. 또한 보안 및 비용 영향을 미칩니다.

이러한 유형의 기능 상태 변경은 종종 다양한 이유로 발생합니다. 순 결과는 팀의 효율성을 유지하는 능력을 저해하는 표면을 제거할 기회를 가지려면 자산 대 부채 측면을 사전에 관리해야 한다는 것입니다.

제품 표면을 줄일 기회를 놓치면 조직은 흔하지만 간과되는 유형의 부채, 즉 인지적 부담에 노출됩니다.

인지적 부담: 공유된 부채

인지적 부담은 결정을 내릴 때 머릿속에 담아두어야 하는 정보의 양입니다. DevEx 연구에서는 다음과 같이 정의합니다.

인지적 부담은 개발자가 작업을 수행하는 데 필요한 정신적 처리량을 포함합니다.

제 관점에서 볼 때, 인지적 부담은 제품의 복잡성이 증가함에 따라, 결과적으로 코드 기반과 인프라가 성장함에 따라 증가하는 경향이 있습니다. 다시 말해, 팀의 각 구성원이 진행하기 위해 관리해야 하는 인지적 부담의 양에 관한 것입니다.

Martin Fowler의 말처럼:

프로그래머는 대부분의 시간을 코드 수정에 소비합니다. 새로운 시스템에서도 거의 모든 프로그래밍은 기존 코드 기반의 컨텍스트 내에서 수행됩니다. 소프트웨어에 새로운 기능을 추가하고 싶을 때, 제 첫 번째 과제는 이 기능이 기존 애플리케이션의 흐름에 어떻게 들어맞는지 파악하는 것입니다. 그런 다음 내 기능이 들어맞도록 흐름을 변경해야 합니다. 종종 애플리케이션에 이미 있는 데이터를 사용해야 하므로, 데이터가 무엇을 나타내는지, 주변 데이터와 어떻게 관련되는지, 그리고 내 새로운 기능에 필요한 데이터를 이해해야 합니다.

고품질 소프트웨어는 비용 가치가 있는가?

지식 작업을 수행할 때 한 사람이 정신적인 스크래치 패드에 담을 수 있는 정보는 한계가 있습니다. 인지적 부담의 영향과 우리 뇌가 작업을 수행하기 위해 임시 기억과 장기 기억을 어떻게 관리하는지 분석하는 많은 연구가 있습니다. George A. Miller에 따르면, 우리는 머릿속에 한 번에 약 7개의 지식 요소를 유지할 수 있습니다.

이제 전자 상거래 사이트의 회원에게 할인을 계산하는 공식이 어떻게 되는지와 같이 사소한 변경을 해야 하는 개발자라고 상상해 보십시오. 최소한 공식에 대한 코드가 어느 파일에 있는지 알아야 합니다. 바라건대, 변경 사항을 쉽게 검증할 수 있도록 해당 테스트 파일을 쉽게 찾을 수 있을 것입니다. 어쩌면 새로운 공식은 할인이 어떻게 계산되는지 더 잘 전달하기 위해 UI에 새로운 복사본이 필요할 수도 있습니다. 이제 최근에 기존 공식으로 할인을 받은 고객에게 무엇을 하고 있습니까? 바우처를 받을 것이라는 이메일을 보내고 싶을 수도 있습니다. 이메일을 보내는 코드는 어디에 있습니까? 고객에게 이메일을 보내는 데 사용할 수 있는 도구는 무엇입니까? 이 변경 사항을 어떻게 배포합니까? 기능 플래그 메커니즘이 있습니까? 변경 사항의 릴리스와 동기화해야 할 마케팅 계획이 있습니까?

보시다시피, 당면한 변경 사항에 대해 추론하는 데 필요한 상당한 양의 임시 지식에 쉽게 도달할 수 있습니다. 이 지식을 얼마나 쉽게 발견할 수 있는지가 원하는 변경 사항을 얼마나 쉽게 수행할 수 있는지에 영향을 미칩니다.

인지적 부담이 변경하는 데 걸리는 시간에 미치는 영향

이것은 개발자에게만 해당되는 문제가 아닙니다. 제품 관리자, 테스트 엔지니어, 디자이너 및 새로운 기능을 설계하고 제공하는 데 관련된 다른 모든 역할은 다음 기능이 어떻게 작동할지에 대한 유용한 정보를 제공하기 위해 제품이 이미 수행하고 있는 작업에 대한 공유된 이해를 유지해야 합니다.

개발자의 경우, 변경하기 전에 기존 코드를 이해하는 데 더 많은 시간을 소비하여 배포 시간이 느려질 수 있다는 것을 의미할 수 있습니다. 관련된 모든 시나리오를 염두에 둘 수 없기 때문에 엣지 케이스를 놓쳐 미묘한 버그가 발생할 수 있습니다.

제품 관리자의 경우, 기존 기능과 조화롭게 작동하는 새로운 기능을 지정하는 데 어려움을 겪을 수 있다는 것을 의미할 수 있습니다. 전체 제품 표면이 너무 복잡해져서 효과적으로 추론할 수 없게 되었기 때문에 새로운 기능이 기존 기능과 충돌하거나 중복되는 방식을 간과할 수 있습니다.

디자이너의 경우, 종종 일관성과 직관성을 유지해야 하는 끊임없이 확장되는 UI 패턴 및 상호 작용 집합과 씨름하는 것을 의미합니다. 각 새로운 기능은 기존 패턴과 조화시켜야 하는 사용자 경험에 또 다른 복잡성 계층을 추가합니다.

조직은 다양한 지표를 통해 이러한 인지적 부담을 측정할 수 있습니다. 겉보기에 관련 없는 영역에서 버그 발생률이 증가하는 것은 팀이 전체 시스템에 대해 추론하는 데 어려움을 겪고 있음을 나타낼 수 있습니다. 디자인 검토 또는 아키텍처 논의에 소요되는 시간이 늘어나는 것은 팀이 새로운 변경 사항이 기존 제품 표면에 어떻게 들어맞는지 이해하는 데 더 많은 시간이 필요하다는 것을 나타낼 수 있습니다. 새로운 팀원의 온보딩 시간이 길어지는 것은 제품 표면이 너무 복잡해져서 빠르게 파악하기 어렵다는 것을 나타낼 수 있습니다.

제품 표면과 인지적 부담 간의 관계는 단순히 복잡성에 관한 것이 아니라 개발 프로세스의 지속 가능성에 관한 것입니다. 도시의 기반 시설이 기초를 개선하지 않고 새로운 건물을 추가하는 것이 지속 불가능해지는 시점에 도달할 수 있는 것처럼, 제품도 인지적 부담을 관리하지 않고 새로운 기능을 추가하는 것이 역효과를 낼 수 있는 시점에 도달할 수 있습니다.

그렇기 때문에 조직이 제품 표면을 늘리도록 팀을 이끄는 지표뿐만 아니라 조직의 전반적인 효율성에 대한 더 높은 수준의 관점을 유지하는 지표를 측정하여 이러한 긍정적인 태도를 촉진하는 것이 중요합니다.

인센티브 시스템

조직은 측정하는 것에 최적화하는 경향이 있습니다. 현재의 메트릭 집합은 제품 팀의 결정을 주도하는 인센티브 시스템의 기초입니다.

팀은 일반적으로 제 시간에(로드맵은 어떻게 진행되고 있습니까?) 그리고 품질 있게(팀의 버그 또는 회귀 추세는 어떻습니까?) 제공하는 능력으로 측정됩니다. 팀의 버그 발생률이 높거나 배포 속도가 느린 이유는 무엇입니까? 제품 표면의 크기는 팀의 성과를 평가할 때 거의 고려되지 않지만, 제 경험상으로는 답의 일부입니다.

제품의 겉보기에 관련 없는 부분에서 발생하는 엣지 케이스는 팀이 작업 중인 제품 영역에 대해 추론하는 데 필요한 인지적 부담으로 어려움을 겪고 있음을 나타낼 수 있습니다. 그러나 품질이 악화되면 제품 표면을 줄이는 것을 목표로 하는 조치를 취하는 경우는 거의 없습니다. 오히려 더 많은 제약 조건("모든 새로운 기능 릴리스는 수동으로 승인되어야 함" 또는 "모든 새로운 기능의 코드 커버리지는 최소 X%여야 함")을 도입하지만, 동일하지는 않더라도 더 높은 처리량을 목표로 합니다.

고객 가치와 직접적인 관련이 없는 작업은 눈살을 찌푸리거나 팀이 현재 주기에서 기능 작업을 하기에 충분히 바쁘지 않을 때 수행할 수 있는 임의적인 고정된 용량으로 남겨둡니다.

조직이 주로 처리량에 집중한다면, 팀에게 가치를 창출하지 않는 코드와 제품 표면을 제거할 여지를 주지 않습니다. 예를 들어, 팀이 "고객 가치와 직접적인 관련이 없기 때문에" 기술 부채를 해결하는 것을 정당화하는 데 어려움을 겪는 것은 드문 일이 아닙니다. 이는 모든 노력이 고객 가치 렌즈를 통해서만 평가되기 때문입니다.

기능 배포를 넘어서: 가치 재정의

모든 노력을 고객 가치 기준으로만 추정하는 것은 조직이 중요한 효율성 기회를 놓치게 하는 결함이 있고 제한적인 관점을 제공합니다. 제품 및 코드 표면을 줄이는 것은 단순한 정리 작업이 아니라 더 높은 수준의 성과를 유지하기 위한 실제적인 전략적 조치입니다.

John Cutler의 말을 바꿔 말하면, 산출물만 측정하고 촉진한다면 기능 공장을 얻게 될 것입니다. 그러나 기능 공장은 지속 가능한 제품 표면에 최적화되어 있지 않습니다. 그들은 끊임없이 증가하는 제품 표면에 최적화되어 있습니다. 다른 모든 것은 그 기능이어야 합니다.

고객 가치에 집착하는 것이 문제가 아니라, 그렇게 하는 데 비효율적이 되는 것이 문제입니다. 우리는 종종 기존 제품 표면의 지속 가능성을 간과하고 새로운 기능을 우선 순위로 지정할 수밖에 없는 조직으로 변모합니다. 왜냐하면 그것이 고객 가치를 제공하는 가장 좋은 방법이라고 믿기 때문입니다.

우리는 배포 능력에 지속적인 긍정적인 영향을 미치는 활동을 수행할 수 있도록 어려움을 겪을 필요가 없습니다. 예를 들어, 사용하지 않는 기능을 제거하는 데 자원과 역량을 투입하는 것은 로드맵에서 이류 시민 항목이 되어서는 안 됩니다.

그렇다면 우선 순위 결정을 내릴 때 궁극적인 북극성으로 고객 가치를 조직 가치로 대체해야 할까요? 관찰과 데이터로 뒷받침되는 새로운 주요 기능에 대한 작업은 인지적 부담을 줄이고 제품에 대해 추론하는 능력을 극대화하는 작업과 동일한 가치를 가져야 할까요?

지속 가능한 제품 조직 만들기

끊임없이 증가하는 제품 표면은 조직이 운영하고 있을 수 있는 결함 있는 인센티브 시스템의 결과입니다. 간략히 논의했듯이, 제품이 원하는 고객 가치를 창출하고 있는지 주시하면 기존 제품 제공의 지속 가능성을 신중하게 관리해야 합니다.

조직이 산출물을 생산하고 로드맵의 다음 항목으로 이동하도록만 인센티브를 받으면 경로를 수정하고 건전한 자산 대 부채 비율을 유지할 기회를 놓치게 됩니다. 제품 팀의 의견은 팀이 역량을 할당하는 방법에 대한 유일한 주요 동인이 될 수 있습니다.

순수한 고객 가치에서 조직 가치로 북극성을 전환하려면 조직은 성공을 측정하는 새로운 방법이 필요합니다. 이러한 측정은 작업의 즉각적인 영향과 배포에 대한 조직의 장기적인 능력에 미치는 영향을 모두 포착해야 합니다.

시스템 건전성 지표

  • 변경 영향 반경: 일반적인 변경에 대해 시스템의 몇 부분이 일반적으로 수정되어야 합니까?
  • 통합 복잡성: 일반적인 기능에 대해 이해해야 하는 시스템 종속성의 수는 얼마입니까?
  • 코드 변동 패턴: 빈번한 수정이 필요한 영역은 제대로 이해되지 않거나 지나치게 복잡한 기능을 나타낼 수 있습니다.
  • 빌드 및 배포 시간: 시간이 늘어나는 것은 종종 시스템 복잡성이 증가하고 있음을 나타냅니다.
  • 테스트 커버리지 추세: 중요한 영역에서 커버리지가 감소하는 것은 복잡성이 증가하여 테스트가 더 어려워지고 있음을 나타낼 수 있습니다.

팀 효율성 지표

  • 팀 간 종속성: 기능 배포에 일반적으로 참여하는 팀의 수는 얼마입니까?
  • 디자인 검토 복잡성: 구현 대비 디자인 논의에 소요되는 시간은 얼마입니까?
  • 기능 개발 주기 시간: 복잡성으로 인해 배포가 느려지는 위치를 식별하기 위해 제품 영역별로 추적됩니다.
  • 회귀 빈도: 변경으로 인한 의도하지 않은 부작용의 비율은 얼마입니까?

자산 대 부채 지표

  • 기능 사용량 대비 유지 관리 비용
  • 기능별 고객 지원 부담
  • 기능별 수익 또는 사용자 참여도
  • 기술 부채 누적 속도
  • 다양한 유형의 작업에 대한 지연 비용

이러한 지표는 조직 가치에 대한 보다 완전한 그림을 그리는 데 도움이 됩니다. 예를 들어, 변경 영향 반경을 줄이거나 이해하는 데 걸리는 시간을 단축하는 작업은 향후 변경 사항을 효율적으로 배포하는 팀의 능력을 향상시켜 조직 가치를 창출합니다. 마찬가지로, 사용하지 않는 기능을 제거하면 즉각적인 고객 가치는 없을 수 있지만 유지 관리 비용과 인지적 부담을 크게 줄일 수 있습니다.

이러한 전환을 위해서는 조직 전체에서 훨씬 더 높은 수준의 투명성이 필요합니다. 팀은 비즈니스 우선 순위가 무엇인지 훨씬 더 잘 이해해야 하며 즉각적인 고객 가치로 직접 전환되지 않을 수 있는 변경을 수행할 수 있는 권한이 있어야 합니다.

조직은 이러한 지표를 정기적으로 검토하고 그에 따라 우선 순위를 조정하기 위한 정기적인 주기를 설정해야 합니다. 예를 들어, 시스템 건전성 지표가 부정적인 추세를 보이면 팀은 새로운 기능보다 간소화 작업을 우선 순위로 지정해야 할 수 있습니다. 팀 효율성 지표가 특정 영역에서 마찰이 증가하고 있음을 보여주면 아키텍처 변경 또는 팀 재구성이 필요함을 나타낼 수 있습니다.

Cutler의 기능 공장에 대한 게시물에서 강조된 것처럼, 많은 개발 팀이 수행하는 것처럼 제품 결정을 내리는 팀이 결정의 질을 측정하고 그에 따라 조정할 수 있도록 적절한 회고 시스템을 갖추는 것이 중요합니다. 이러한 회고는 즉각적인 결과와 조직 능력에 대한 장기적인 영향을 모두 명시적으로 고려해야 합니다.

나아갈 방향

제품 표면과 조직 효율성 간의 관계는 복잡하지만 이해하는 것이 중요합니다. 살펴본 바와 같이, 끊임없이 확장되는 제품 표면은 복합적인 효과를 생성합니다. 각 새로운 기능은 자체적인 복잡성을 추가할 뿐만 아니라 시스템 전체를 이해하고 수정하는 데 필요한 인지적 부담을 증가시킵니다.

이러한 역학은 어려운 긴장을 만듭니다. 조직은 경쟁력을 유지하기 위해 고객 가치를 제공해야 하지만, 기능 추가를 통해서만 그렇게 하는 것은 제품 표면의 지속 불가능한 성장으로 이어집니다. 해결책은 새로운 기능을 구축하는 것을 중단하는 것이 아니라 제품 표면 관리를 순전히 기술적인 문제가 아닌 전략적인 문제로 인식하는 것입니다.

성공하려면 여러 수준에서 변화가 필요합니다.

첫째, 조직은 즉각적인 고객 대면 기능을 넘어 가치에 대한 정의를 확장해야 합니다. 인지적 부담을 줄이거나 사용하지 않는 기능을 제거하거나 시스템을 이해하고 수정하는 팀의 능력을 향상시키는 작업은 새로운 기능 개발과 동등하게 평가되어야 합니다.

둘째, 측정 시스템이 발전해야 합니다. 배포 속도와 버그 수에만 초점을 맞춘 기존 메트릭은 시스템 지속 가능성이라는 중요한 차원을 놓치고 있습니다. 팀에게는 인지적 부담, 제품 표면의 효율성, 변경 사항을 안전하고 자신감 있게 배포할 수 있는 능력을 측정하고 모니터링할 수 있는 방법이 필요합니다.

마지막으로, 팀은 제품 표면을 적극적으로 관리하도록 인센티브를 받아야 합니다. 이는 기존 기능에 대한 정기적인 평가, 기능을 제거할 시점에 대한 신중한 결정, 새로운 기능이 전체 시스템 복잡성에 미치는 영향에 대한 신중한 고려를 의미합니다.

장기적으로 번성할 조직은 새로운 가치를 제공하는 것과 제품 표면을 효과적으로 관리하는 것 사이의 건전한 균형을 유지할 수 있는 조직입니다. 이를 위해서는 소프트웨어를 자산으로만 보는 것에서 벗어나 효과성을 유지하기 위해 지속적인 큐레이션이 필요한 역동적인 시스템으로 이해하는 사고방식의 전환이 필요합니다.

문제는 제품 표면을 관리해야 하는지 여부가 아니라, 어떻게 의도적이고 효과적으로 관리할 것인지입니다.