-
복잡성은 개발에서 가장 위험한 요소임
- 진정한 효율성은 "80/20 솔루션" 등 복잡성을 피하는 실용주의적 접근에서 나옴
-
테스트와 리팩터링에 대해 균형 있고 유연한 자세를 유지하는 것이 중요함
-
도구 활용 및 읽기 쉽고 관리하기 쉬운 코드 작성 습관 채택을 강조함
- 과도한 추상화와 트렌드를 경계하며, 단순성을 추구하는 태도를 추천함
서론
- 이 글은 오랜 기간 소프트웨어를 개발하며 경험에서 배운 점을 정리한 그럭 브레인 개발자의 생각 모음임
- 그럭 브레인 개발자는 스스로 똑똑하지 않다고 생각하지만, 오랜 시간동안 프로그래밍을 하며 많은 것을 배움
- 다른 사람들이 실수에서 배우기를 바라는 마음으로 쉽고 웃긴 방식으로 깨달음을 공유함
-
복잡성이야말로 개발 인생의 최대의 적임
- 복잡성은 코드베이스에 몰래 침투하여, 처음엔 이해하기 쉽던 코드도 점차 수정이 불가능한 지경에 이르게 만듦
복잡성의 악령 다루기
- 복잡성은 보이지 않는 영처럼 소리 없이 스며들며, 프로젝트 매니저 및 비그럭 개발자들이 잘 인식하지 못하는 경우가 많음
- 복잡성을 막는 최고의 방법은 "아니오"라고 말하는 것임
- "이 기능을 만들지 않겠다"
- "이 추상화를 도입하지 않겠다"
- 물론, 커리어 면에서는 "예"를 외치는 것이 더 이득일 수 있지만 그럭 브레인 개발자는 스스로에게 정직한 선택을 중시함
- 조건에 따라 타협(“ok”)도 필요하며, 이런 경우 80/20 솔루션(Pareto 법칙 적용)으로 문제를 단순하게 해결하는 방식을 선호함
- 프로젝트 매니저에게 모든 것을 말하지 않고 실제로는 80/20 방식으로 해내는 것도 현명한 전략임
코드 구조와 추상화
- 코드의 적절한 단위(컷포인트)는 시간이 지나면서 자연스럽게 드러남, 그래서 초반의 추상화는 피하는 것이 좋음
- 좋은 컷포인트는 시스템 나머지와의 인터페이스가 좁은 것이 이상적임
- 조기 추상화 시도는 실패하기 쉽고, 경험 많은 개발자는 코드의 형태가 어느 정도 자리를 잡은 뒤에 천천히 구조화를 시도함
- 경험이 적거나 “빅브레인”인 개발자들은 프로젝트 초기에 지나친 추상화를 시도하며, 유지보수의 부담을 남겨둠
테스트 전략
-
테스트에 대한 집착과 균형이 중요함
- 프로토타이핑 후, 코드가 어느 정도 고정된 뒤에 테스트를 짜는 것을 선호함
- 유닛 테스트는 초기에 활용하지만, 실제로는 중간 단계(통합 테스트)가 가장 큰 효과를 보임
- 엔드 투 엔드 테스트도 필요하지만, 너무 많으면 유지보수 불가 상황이 오므로 꼭 필요한 경로만 소수로 유지
- 버그 리포트 시에는 반드시 재현 테스트 추가 후 버그를 고침
프로세스, 애자일, 리팩터링
-
애자일은 그럭 개발자에게 나쁘지 않으며, 최악도 아니지만, "애자일 샤먼"에게 과도한 기대는 위험
- 프로토타이핑, 도구, 좋은 동료가 실제로 더 중요한 성공 요소
- 리팩터링도 좋은 습관이지만, 크고 무리한 리팩터링은 위험함
- 복잡한 추상화를 무리하게 도입하는 것이 오히려 프로젝트 실패를 초래함
유지보수, 완벽주의와 겸손
- 기존 시스템을 이유 없이 뜯어고치는 것은 위험하며, “왜 있는지 모르는 구조”를 무작정 없애는 것은 좋지 않은 습관임
- 완벽한 코드를 꿈꾸는 이상주의는 현실적으로 대부분 문제를 야기함
- 경험이 쌓일수록 “동작하는 코드는 존중”해야 함을 몸소 느낌
도구와 생산성
- 좋은 개발 도구(IDE 코드완성, 디버거 등)는 생산성을 크게 높여주며, 깊게 파악하는 것이 중요함
- 타입 시스템의 실제 가치는 “자동 완성”과 실수 방지에 있음을 강조하고, 과도한 추상화와 제네릭은 오히려 위험함
코드 스타일과 반복
- 더 읽기 쉽고 디버깅하기 쉬운 코드를 위해 조건식을 여러 줄로 쪼개는 식의 스타일 권장
-
DRY(Don’t Repeat Yourself) 원칙은 존중하지만, 반복 코드를 무리하게 없애는 것보단 균형이 중요한 점을 강조함
- 단순 반복이 복잡한 DRY 구현보다 나은 상황도 많음
소프트웨어 설계 원칙
-
SoC(관점 분리) 원칙보다 행동 지역성을 선호, "해당 동작을 하는 코드가 그 객체에 있어야 유지보수가 쉬움"을 주장
- 콜백/클로저, 타입 시스템, 제네릭, 추상화 등은 소량만 적절히 사용할 것을 경고함
- 클로저의 남용은 자바스크립트에서 "콜백 지옥"을 만들 수도 있음
로깅, 운영
-
로깅은 매우 중요한데, 주요 분기마다 남기고, 클라우드 환경에서는 요청 ID 등으로 추적 가능하게 구성함
- 동적 로그 레벨, 사용자별 로그를 활용할 수 있으면, 운영 중의 문제 추적에 큰 도움이 됨
동시성, 최적화
-
동시성은 최대한 단순한 모델(상태 없는 웹 요청, 분리된 워커 큐 등)만 신뢰
- 최적화는 실제 성능 프로파일 데이터를 확보한 후에만 실제로 수행하기를 권장
- 네트워크 I/O 등 숨겨진 비용에 주의해야 하며, 단순히 CPU 복잡도만 보는 것은 위험함
API 설계
- 좋은 API는 사용하기 쉬워야 하며, 너무 복잡한 설계나 추상화는 개발자 경험을 해침
- "사용 케이스에 맞는 단순한 API"와 "복잡한 케이스도 구현 가능한 계층적 API" 구조를 권장함
파서 개발
- 재귀하강 파서는 학계에서 저평가되지만, 실제 생산 코드에 가장 적합하고 이해하기 쉬운 방법임
- 대부분의 파서 개발 경험상, 툴로 생성한 파서는 결과물이 너무 복잡해 문제 해결에 오히려 마이너스임
- 추천 도서로 "Crafting Interpreters"를 최고로 꼽으며 실무적인 조언을 많이 담고 있음
프론트엔드와 유행
- 모던 프론트엔드(React, SPA, GraphQL 등)는 오히려 복잡성 악령을 추가로 불러오며, 불필요한 경우가 많음
- Grug 본인은 htmx, hyperscript 같은 단순한 도구를 통해 복잡성을 줄이는 방식을 선호함
- 프론트엔드에서 끊임없이 새로운 시도가 이뤄지고 있지만, 기존 아이디어의 반복이 많음에 유의할 필요가 있음
심리적 요소, 임포스터 신드롬
- 대부분 개발자들은 “내가 뭘 하는지 모른다”고 느낄 때가 많으며, FOLD(Fear Of Looking Dumb) 현상에서 자유로워질 필요가 있음
- 선임 개발자가 “이건 나도 어렵다, 너무 복잡하다”고 공개적으로 말하면, 주니어 개발자도 부담을 내려놓을 수 있음
- 임포스터 신드롬은 흔한 감정이며, 충분히 배워가며 성장할 수 있음을 격려함
결론
- 프로그래밍에서 복잡성은 항상 경계해야 하며, 단순함 유지는 성공적 개발의 핵심임
- 경험, 도구의 효과적 활용, 겸손, 실제로 동작하는 코드의 존중이 장기적으로 효율적이고 가치 있는 개발로 이어짐
- "복잡성 매우, 매우 나쁨"—이 문장을 항상 기억해야 함