#acl +All:read = WorkingFirst = ''주니어 개발자들을 위한 패턴 언어 - 우아함보다 먼저 작동하는 실체를 만들어 진실을 드러내는 법'' <> == The Story 1: The Perfectionist vs. The Snowballer (Programming) == 두 명의 개발자, 민수와 하나가 '새로운 알림 엔진'을 만들고 있다. '''민수의 방식 (The Perfectionist):''' 민수는 처음부터 확장 가능하고 우아한 설계를 꿈꾼다. 그는 인터페이스를 설계하고, 추상 클래스를 만들고, 디자인 패턴을 적용하느라 사흘을 보냈다. 하지만 사흘째 되는 날에도 알림은 단 한 건도 발송되지 않았다. 설계도만 거창할 뿐, 실제로 무엇이 문제일지는 여전히 미지수였다. '''하나의 방식 (The Snowballer):''' 하나는 다르게 시작했다. 일단 `print("알림 발송!")`이라는 한 줄의 코드로 시작했다. 그 다음, 하드코딩된 이메일 주소로 진짜 메일이 가는지 확인했다. "일단 돌아가네. 이제 여기서부터 하나씩 붙여보자." 하나는 한 시간 만에 '작동하는 실체'를 만들었다. 그 실체는 하나에게 어디가 병목인지, 어떤 예외 처리가 진짜 필요한지 알려주었다. 작은 눈덩이(Snowball)는 구를수록 커져서 저녁 무렵엔 견고한 엔진이 되었다. == The Story 2: The Signature Dish (Ordinary Life) == 민수와 하나는 친구들을 초대해 저녁 식사를 대접하기로 했다. 메뉴는 한 번도 안 해본 복잡한 '프랑스 요리'다. '''민수의 요리 (The Ideal Recipe):''' 민수는 요리책을 수십 번 읽으며 완벽한 타이밍과 도구를 준비했다. 하지만 정작 요리를 시작하자 생각지 못한 변수가 발생했다. 화력이 책과 달랐고, 재료의 수분기도 달랐다. 민수는 당황했고 저녁 식사는 엉망이 되었다. '''하나의 요리 (The Prototype Meal):''' 하나는 전날 밤, 아주 적은 양의 재료로 핵심 소스만 미리 만들어보았다. "아, 이 소스는 생각보다 빨리 타는구나. 설탕을 좀 줄여야겠어." 하나는 아주 간단한 버전으로 '맛'을 먼저 확인했다. 이 작은 실험 덕분에 하나는 실제 요리에서 불 조절을 어떻게 해야 할지 정확히 알게 되었고, 친구들에게 완벽한 식사를 대접할 수 있었다. 기예는 이론이 아니라 '작동하는 경험'에서 시작됨을 하나는 알고 있었다. == Context == 새로운 기능을 구현하거나 복잡한 문제를 해결해야 한다. 머릿속에는 거창한 설계가 떠오르지만, 어디서부터 손을 대야 할지 막막한 상황이다. 일상적인 상황: * 완벽한 설계를 하려다 시작도 못 하고 시간을 보낸다. * "나중에 고생 안 하려면 처음부터 제대로 짜야 해"라는 압박을 느낀다. * 코드를 짜는 시간보다 화이트보드 앞에서 고민하는 시간이 훨씬 길다. * 구현 도중 예상치 못한 기술적 난관에 부딪혀 전체 설계를 뒤엎는다. == Problem == '''실행 없는 완벽한 설계는 가설일 뿐이며, 실제 구현 단계에서 나타나는 수많은 변수를 예측하지 못한다.''' * '''피드백 지연:''' 실제로 돌아가는 것을 보기 전까지는 내 생각이 맞는지 틀린지 알 수 없다. * '''심리적 부담:''' 완벽해야 한다는 생각은 행동을 느리게 만들고 창의성을 억누른다. * '''매몰 비용:''' 거창하게 설계한 뒤에는 나중에 결함을 발견해도 설계를 바꾸기가 아까워진다. == Solution == '''우아하거나 효율적으로 만들기 전에, 가장 단순한 형태로 "먼저 작동하게" 만들어라.''' 작동하는 해결책은 문제의 진정한 본질을 드러내고, 당신이 가야 할 다음 길을 안내한다. === Principle 1: Make it Work, Then Make it Right === Kent Beck의 조언을 기억하라. 1. 작동하게 만들어라 (Make it Work). 2. 올바르게 만들어라 (Make it Right - 리팩토링). 3. 빠르게 만들어라 (Make it Fast - 최적화). 대부분의 주니어는 1단계를 건너뛰고 2단계나 3단계부터 하려다 길을 잃는다. === Principle 2: Use Familiar Tools First (익숙한 도구로 뚫기) === 새로운 기술 스택이나 과제 조건에 얽매여 전진을 멈추지 마라. * Tailwind가 익숙하지 않다면 Custom CSS로, HTMX가 헷갈린다면 jQuery나 순수 JavaScript로 일단 동작하게 만들어라. * 통 페이지 새로고침(Web 1.0 방식)으로라도 기능을 먼저 완성한 뒤, 시간이 남으면 그때 요구된 기술 스택으로 리팩토링하라. === Principle 3: Snowballing from a Small Core === 작고 초라한 시작을 부끄러워하지 마라. * `Hello World`가 찍히는 순간 당신은 불확실성의 50%를 제거한 것이다. * 작은 성공의 경험은 눈덩이처럼 불어나 당신에게 설계를 완성할 자신감과 데이터를 제공한다. == Real Examples == === Example 1: Sketching first === 화가들은 눈동자의 디테일을 그리기 전에 전체 구도를 연필로 슥쓱 그린다. 엉성한 선들이 모여 전체적인 균형을 잡은 뒤에야 세밀한 묘사에 들어간다. === Example 2: Tracer Bullets === 어두운 밤, 목표를 맞추기 위해 계산기만 두드리는 대신 '예광탄'을 쏜다. 탄환이 날아가는 궤적을 눈으로 확인하면, 조준경을 어떻게 수정해야 할지 즉시 알 수 있다. == Common Pitfalls == === "Dirty Code Guilt" (더러운 코드에 대한 죄책감) === 일단 작동하게 만들 때 나오는 지저분한 코드에 괴로워하는 것. * 이것은 최종 결과물이 아니라 '탐색을 위한 도구'다. [[BabySteps]]와 [[GreenRefuge]]가 있다면 언제든 깨끗하게 고칠 수 있다. === Stopping at "Working" (작동만 한다고 멈추는 것) === 작동하게 만든 뒤 '올바르게' 만드는 과정을 생략하는 것. * 그것은 성장이 아니라 부채를 쌓는 일이다. 반드시 리팩토링 과정을 거쳐야 한다. == Connection to Other Patterns == * '''[[TinyExperiment]]''' - WorkingFirst를 실천하는 가장 구체적인 행동이 작은 실험입니다. ''수단'' * '''[[BabySteps]]''' - 일단 작동시킨 후에는 작은 보폭으로 안전하게 전진하십시오. ''과정'' * '''[[OrganicGrowth]]''' - 작동하는 작은 핵심이 유기적 성장의 씨앗이 됩니다. ''출발점'' * '''[[RoughWholeFirst]]''' - 엉성하게나마 전체가 돌아가게 만드는 것이 WorkingFirst의 지향점입니다. ''관점'' == Signs of Success == * 프로젝트 시작 30분 만에 무언가 실행되는 것을 동료에게 보여줄 수 있다. * "아, 해보니까 이게 문제네요"라는 실질적인 통찰이 쏟아진다. * 설계에 대한 불필요한 논쟁이 줄어들고, 실행 결과에 기반한 대화가 늘어난다. * 막연한 두려움이 사라지고 개발 리듬이 경쾌해진다. == The Ultimate Insight == '''이론은 당신을 생각하게 만들지만, 실행은 당신을 눈뜨게 만든다.''' 완벽한 설계도는 책상 위에만 존재합니다. 진짜 진실은 실행되는 런타임 속에 숨어 있습니다. 거창한 건축을 꿈꾸기 전에 먼저 작은 말뚝 하나를 박으십시오. 그 말뚝이 당신의 설계를 현실로 이끌어줄 것입니다. ---- CategoryPatternLanguage CategoryProgramming CategoryAgile CategoryMindset