나의 노트

초기 개발

Early Development

번역 제공해주신 켄트 벡(Kent Beck)의 "Early Development(초기 개발)" 패턴 문서를 한국어로 번역하여 마크다운(Markdown) 형식으로 정리해 드립니다. 이 문서는 소프트웨어 개발 초기에 고객의 요구사항을 이해하고, 기술적 불확실성을 줄이며, 프로젝트의 방향을 잡는 데 도움이 되는 애자일(Agile) 및 익스트림 프로그래밍(XP)의 핵심 철학을 담고 있습니다. --- c2.com/ppr/early.html ↗

이 패턴들은 시스템 개발을 어떻게 시작할 것인가에 대해 이야기합니다. 고객을 소외시키지 않으면서 어떻게 필요한 정보를 얻을 수 있을까요? 당신의 이해가 프로그램의 요구사항과 일치하는지 어떻게 확인할 수 있을까요? 고객의 생각이 변할 때, 그 피할 수 없는 변화를 어떻게 수용하고 활용할 수 있을까요?

관련된 패턴들은 다음과 같습니다:

  1. 스토리 (Story)
  2. 초기 프로그램 (Early Program)
  3. 아키텍처 프로토타입 (Architecture Prototype)
  4. 인터페이스 프로토타입 (Interface Prototype)

1. 스토리 (Story)

<스토리 이전에 어떤 패턴이 있을까요? 아마도 전산화를 결정하는 것에 대한 내용일 것입니다.> 개발을 어떻게 시작하나요?

당신이 이미 해당 분야의 전문가가 아니라면, 소프트웨어 엔지니어로서 어떤 결정을 내리기 전에 먼저 고객의 전문 분야를 이해하기 시작해야 합니다. 어떻게든, 일을 시작할 수 있을 만큼은 배워야 합니다.

어떤 엔지니어들은 '소프트웨어적 사고방식'으로 개발을 시작합니다. 고객이 말을 꺼내자마자 다이어그램을 그리거나 코딩을 시작하죠. 초기 프로그램(2)에서 보게 되겠지만, 저 역시 프로세스 초기에 프로그래밍을 시작하는 것을 지지합니다. 하지만 처음에는 고객이 프로세스를 주도해야 합니다. 욕구(desires)를 가능성(possibilities)으로 매핑하는 작업을 너무 서두르면, 욕구의 진정한 요점을 놓칠 위험이 있습니다. 종종 고객은 처음 몇 분 동안 개발에 막대한 영향을 미칠 수 있는 미묘한 이야기를 합니다. 만약 당신이 1:1 관계인지 1:n 관계인지를 따지느라 너무 바쁘다면, 이러한 보석 같은 정보를 놓치게 될 것입니다.

반대로 행동하는 엔지니어들도 있습니다. 그들은 개발이 시작되기 전에 모든 요구사항을 수집하고 싶어 합니다. 저는 이것을 "유스케이스 마비(use case paralysis)"라고 부릅니다. "요구사항"이 존재하고 그것을 완벽히 "수집"할 수 있다는 생각은 그 어떤 요인보다도 많은 소프트웨어 프로젝트를 망쳐왔습니다. 이것은 재료를 섞기도 전에 케이크를 구우려는 것과 같습니다. 시스템의 존재, 심지어 시스템을 만드는 과정 자체가 고객이 세상을 바라보는 인식을 변화시킵니다. 실체가 없는 허상(will-o-the-wisp)을 쫓느라 시간, 돈, 에너지를 낭비하는 것보다, 세상이 작동하는 방식을 인정하고 그에 적응하는 것이 낫습니다.

고객의 전문 지식을 어떻게 습득할지 결정할 때 고려해야 할 또 다른 요소는, 자신의 이야기가 경청되고 있다고 느끼고 싶은 인간의 본능적인 욕구입니다. 소프트웨어 개발은 종종 고객의 권한을 박탈하곤 합니다. 그들이 이전에 하던 방식은 무엇이든 영원히 바뀌게 될 것입니다. 하지만 고객의 자발적인 참여 없이는 절대 성공할 수 없습니다. 곧 곤경에 처할지도 모르는 사람에게 어떻게 열정적으로 도와달라고 할 수 있겠습니까?

마지막으로, 당신이 소프트웨어 엔지니어의 관점으로 보는 것을 멈추지 않는 한, 고객 분야의 진정한 전문가가 될 수 없음을 인정하십시오. 아무리 그들의 용어를 잘 배운다 해도, 실제로 그 업무를 수행하는 것은 아닙니다. 다행히도, 효과적인 소프트웨어를 만들기 위해 전문가가 될 필요는 없습니다 (위대한 소프트웨어를 만들기 위해서는 전문가가 되어야 할 수도 있겠지만요). 당신은 단지 고객의 욕구를 현재 컴퓨터의 능력에 매핑할 수 있을 정도만 알면 됩니다. 초기에는 시스템의 진화를 시작할 수 있을 만큼만 이해하면 충분합니다.

따라서: 고객에게 시스템이 어떻게 사용될지에 대한 이야기를 대여섯 개 정도 들려달라고 요청하십시오. 이야기를 시작하기 전에 각 이야기의 교훈이나 요점을 먼저 생각해 보라고 하십시오. 나중에 기록하기 위해 이야기를 녹음하십시오. 도저히 무슨 말인지 모르겠는 상황이 아니라면, 듣는 동안 너무 많은 질문을 하지 마십시오.

이해한 내용을 테스트하고 진화의 과정을 시작하려면 초기 프로그램(2)이 필요합니다.


2. 초기 프로그램 (Early Program)

시스템이 어떤 느낌이어야 하는지를 묘사하는 스토리(1)를 몇 개 가지고 있습니다. 고객이 원하는 것을 소프트웨어로 매핑하기 위해 무엇을 해야 할까요?

어떤 개발자들은 고객의 욕구를 추상적인 소프트웨어로 구체화하기 시작합니다. 그들은 CASE 도구를 사용하여 고객의 도메인을 나타내는 다이어그램을 그립니다. 그러고 나서 소프트웨어를 나타내는 다이어그램을 그립니다. 마지막으로, 그 프로그램을 실행 가능한 형태로 변환합니다.

저는 실행되는 소프트웨어에 대한 이러한 혐오감이 대규모 소프트웨어 개발의 초기 시절에서 비롯되었다고 생각합니다. 프로그래밍의 역사에서 단순히 앉아서 코딩하는 것만으로는 충분하지 않다는 것이 명백해지는 데는 그리 오랜 시간이 걸리지 않았습니다. 체계적인 접근 방식 없이 코딩하는 프로그래머들은 무시당했습니다. "아, 쟤는 그냥 해커일 뿐이야."

초기 코드의 문제는 무엇일까요? 초기의 프로그래밍 스타일, 언어, 환경에서는 '가정(assumptions)'들이 프로그램 전체에 스며드는 것이 일반적이었습니다. 이러한 가정들은 변화에 대한 거대한 관성을 형성했습니다. 따라서 무지한 상태에서 초기에 내린 결정이 나중에 틀린 것으로 판명되면 엄청난 비용이 들었습니다.

고객의 욕구와 그것을 실현하는 소프트웨어를 추상적으로 표현하는 것의 문제는 무엇일까요? 간단히 말해서, 소프트웨어의 품질, 고객 만족도, 진행 상황에 대해 헛소리(bullshit)를 하기가 너무 쉽다는 것입니다. 수천 페이지의 분석 및 설계 다이어그램은 전체 시스템이 어떻게 작동하는지, 심지어 작동은 하는지 아무도 모른다는 사실을 쉽게 감춰버릴 수 있습니다.

시스템 개발에는 진행 상황에 대한 객관적인 척도가 필요합니다. 다이어그램은 모든 단계에서 시스템의 구조와 의도를 전달하는 데 강력한 역할을 합니다. 하지만 다이어그램에만 의존하는 것은 문제를 자초하는 일입니다.

그렇다면 초기 프로그램의 문제는 어떻게 해결할까요? 시스템의 최종적인 니즈를 모른 채 작성되어, 앞서 지적한 막대한 비용을 초래하지 않을까요? 프로그램을 수정하려면 소중한 모든 것을 희생해야 했던 '모놀리스(Monolith)' 시절과는 많은 것이 변했습니다. 다형성(polymorphism)이나 가비지 컬렉션(garbage collection)과 같은 프로그래밍 언어의 추상화는 프로그램의 일부를 다른 부분의 변경으로부터 효과적으로 격리해 줍니다. 대규모 시스템 개발을 지원하는 프로그래밍 환경은 변경 사항을 만들고 검증하는 메커니즘을 쉽게 만들어줍니다. 코드 변경 비용을 줄이는 퍼즐의 마지막 조각이자, 초기 코드를 가치 있게 만들 뿐만 아니라 필수적인 것으로 만드는 요소는 바로 '패턴 주도 개발(pattern guided development)'입니다. 패턴에 기반한 프로그래밍 스타일은 프로그램의 모든 부분이 미래의 진화를 적절히 주시하도록 하며, 코드를 변경하는 것을 불필요하게 방해하는 일이 없도록 보장합니다.

언어, 환경, 패턴이라는 이 요소들의 조합은 급격한 변경에도 비용이 많이 들지 않는 코드를 만들어냅니다. 따라서 새로운 통찰력이 발견되면, 빠르고 적은 비용으로 실행 중인 시스템에 반영할 수 있습니다. 치러야 할 큰 대가가 없다면, 구체적이고 실행되는 소프트웨어의 장점은 압도적입니다.

따라서: 시스템이 스토리들을 어떻게 실행하는지 보여주는 구체적인 소프트웨어를 만드십시오.

그룹으로 작업하는 경우, CRC 카드를 사용하여 시뮬레이션된 소프트웨어를 먼저 만들고 싶을 수 있습니다. 기술적인 이해도가 높은 고객은 아키텍처 프로토타입(3)을 이해할 수 있을 것입니다. 시각적인 것을 선호하는 고객에게는 인터페이스 프로토타입(4)이 도움이 될 것입니다.


3. 아키텍처 프로토타입 (Architecture Prototype)

초기 프로그램(2)을 작성해야 합니다. 개발 초기에는 어떤 종류의 프로그램을 작성해야 할까요?

프로젝트 초기에는 고객과 개발자 모두 흐릿한 망원경을 통해 먼 곳의 물체를 바라보고 있는 상태입니다. 진짜 질문은 '어느 망원경의 초점을 먼저 맞출 것인가?'입니다.

고객의 관점인 사용자 인터페이스(UI)를 프로토타이핑하는 것은 추천할 만한 점이 많습니다. UI는 시스템에서 고객과 개발자가 같은 것을 보고 있는 유일한 지점입니다. 의사소통이 잘되지 않는 고객과 개발자에게 UI 프로토타이핑은 프로젝트의 나머지 기간 동안 서로를 지탱해 줄 공통의 기반을 제공할 수 있습니다.

사용자 인터페이스 프로토타이핑에 대한 주요 반론은 그것이 무엇이 가능한지에 대한 고객의 기대를 너무 일찍 높여버린다는 점입니다. 고객은 시스템처럼 보이는 것을 보자마자 나머지도 다 되었다고 가정할 것입니다. 소프트웨어 개발에 익숙하지 않은 고객들은 화면이 완성된 것처럼 보여도 실제 소프트웨어는 5%만 완성되었다는 말을 들으면 꽤나 공격적으로 변할 수 있습니다.

초기에 결정해야 할 시스템의 또 다른 중요한 측면은 아키텍처입니다. 즉, 주요 구성 요소, 책임의 분배, 제어의 흐름 등을 말합니다. 아키텍처는 전체 개발 팀을 위한 공통의 기반입니다. 팀이 아키텍처에 대한 비전을 공유하기 전까지는 실질적인 진전을 이루기 어렵습니다. 사실, 아키텍처가 부재한 상태에서 작성된 코드는 추후 개발 속도를 늦출 수도 있습니다.

따라서: 개발자들에게 중요한 공유 책임(shared responsibilities)을 전달하는 아주 작은 시스템을 작성하십시오. 각 객체(Object)에는 소수의 메서드만 부여하십시오. 유연성보다는 가독성을 최우선으로 최적화하십시오.

사용자 객체(User's Object)로 시스템을 시작하십시오. 문학적 프로그래밍(Literate Program) 방식으로 프로토타입을 문서화하십시오.


4. 인터페이스 프로토타입 (Interface Prototype)

초기 프로그램(2)을 작성해야 합니다. 개발 초기에는 어떤 코드를 작성해야 할까요?

어떤 개발자들은 시스템을 어떻게 작동시킬지에만 너무 집중한 나머지, 한 걸음 물러서서 고객의 관점에서 시스템을 이해하지 못합니다. 그들은 고객 도메인에 대한 얄팍한 이해만 가지고 무작정 달려듭니다. 이런 환경에서 개발된 시스템은 종종 기술적으로는 아름답지만 쓸모가 없어, 개발 투자에 대한 보상을 제공하지 못합니다. 개발자들은 "고객의 신발을 신고 1마일을 걸어봐야(고객의 입장이 되어봐야)" 합니다.

고객들은 종종 반대의 문제를 겪습니다. 그들은 장대하고 영광스러운 미래에만 너무 집중한 나머지 무엇을 먼저 해야 할지 집중하지 못합니다. 이 '질병'의 증상은 시스템 개념이 몇 가지 중요 항목(bullet items)이나 비기술적인 고객이 그린 아키텍처 다이어그램보다 더 구체화되지 않는 것입니다. 초점이 없는 고객을 둔 시스템은 수명 초기 단계에서 극심한 혼란(thrashing)을 겪습니다. 고객은 우선순위를 정해야 합니다.

따라서: 가장 중요한 스토리(1)를 지원하는 데 필요한, 사용자가 볼 수 있는 부분(user visible portion)을 작성하십시오.

사용자 인터페이스(User Interface)를 구축해야 할 것입니다.


Author: Kent Beck, First Class Software, Inc. Copyright: 1995, First Class Software, Inc. All rights reserved


💡 다음 단계

이 번역이 도움이 되셨나요? 이 "초기 개발" 단계 이후에 이어질 수 있는 구체적인 유저 스토리 작성법이나 CRC 카드 활용법에 대해 더 자세히 알아보고 싶으시다면 말씀해 주세요.


gemini 3 pro 질답
Q. 유연성보다 가독성을 최우선으로 하라는 이유는?
A.
켄트 벡이 아키텍처 프로토타입(Architecture Prototype) 단계에서 "유연성(Flexibility)보다 가독성(Readability)을 최우선으로 하라"고 강조한 이유는 이 단계의 목적이 '완벽한 제품'을 만드는 것이 아니라 '팀원 간의 소통과 합의'이기 때문입니다.

구체적인 이유는 다음과 같습니다.

  1. 프로토타입은 '소통 도구'입니다

이 단계에서 작성하는 코드는 컴퓨터를 실행시키기 위한 것이기도 하지만, 주된 독자는 동료 개발자들입니다.

목표: 팀 전체가 "아, 우리 시스템의 핵심 구조는 이렇게 생겼구나", "데이터는 이렇게 흐르는구나"라는 공통된 비전(Shared Vision)을 갖는 것입니다.

이유: 코드가 유연성을 위해 각종 추상화(인터페이스, 팩토리 패턴, 복잡한 상속 등)로 덮여 있으면, 동료들이 코드의 핵심 흐름을 한눈에 파악하기 어렵습니다. 지금은 "무엇이든 할 수 있는 만능 칼"을 보여줄 때가 아니라, "이 칼의 손잡이는 여기고 날은 여기다"라는 명확한 구조를 보여줘야 할 때입니다.

  1. 불필요한 복잡성(Over-engineering) 방지

개발 초기에는 미래에 어떤 변경 사항이 생길지 정확히 알 수 없습니다.

유연성의 함정: 아직 오지도 않은 미래의 요구사항을 대비해 유연하게 만들다 보면, 코드가 불필요하게 복잡해집니다(YAGNI 원칙 위배). 이는 초기 개발 속도를 늦추고, 팀원들에게 혼란만 줍니다.

가독성의 이점: "A가 B를 호출한다"처럼 직관적이고 단순하게 짜여진 코드는 누구나 쉽게 이해하고 수정할 수 있습니다. 켄트 벡이 말하는 '패턴 주도 개발'에서는 나중에 필요할 때 리팩터링을 통해 유연성을 추가하는 것이 훨씬 비용이 적게 든다고 봅니다.

  1. '정확한' 피드백을 받기 위함입니다

아키텍처 프로토타입은 검증을 위한 것입니다.

코드가 너무 유연해서 모든 상황을 처리할 수 있게 짜여 있다면, 오히려 제약 조건(Constraint)이 무엇인지 알기 어렵습니다.

코드를 단순하고 명확하게(가독성 높게) 작성해야, 설계상 빈틈이나 논리적 오류가 눈에 확 띕니다. 복잡한 추상화 뒤에 숨겨진 문제는 찾기 어렵습니다.

  1. 진입 장벽 낮추기

초기 아키텍처는 프로젝트 내내 새로운 개발자가 합류하거나 다른 팀원이 코드를 볼 때 '지도' 역할을 해야 합니다.

지도가 너무 복잡하면(유연하면) 길을 찾을 수 없습니다.

단순하고 읽기 쉬운 코드는 팀원들이 시스템의 전체 그림을 빠르게 머릿속에 그릴 수 있게 도와줍니다.

요약하자면 이 시점의 코드는 "나중에 바꾸기 쉽게 만드는 것(유연성)"보다 "지금 당장 우리가 무엇을 만들고 있는지 모두가 똑같이 이해하게 만드는 것(가독성)"이 훨씬 중요하기 때문입니다.