실용주의 프로그래머를 읽고

프로그래밍 명저 시리즈 중 첫 책으로 실용주의 프로그래머를 골랐다. 순서 없이 읽어도 되는 책을 굳이 순서대로 읽으면서, 공감한 토픽과 끝내 공감하지 못한 토픽을 나눠 기록한다.

Development·
실용주의 프로그래머 책 사진

이 책을 읽게 된 계기

프로그래밍 명저 시리즈는 워낙 유명하다. 테스트 주도 개발, 클린 코드 같은 책은 개발자라면 한 번쯤 읽어봤거나 최소한 들어는 봤을 것이다. 그런데 나는 이 시리즈 중에 한 권도 제대로 읽어본 적이 없었다.

무슨 책부터 읽을까 하다가 실용주의 프로그래머를 골랐다. 이유는 이랬다.

  • 주로 회사에서 0 to 1 프로젝트를 진행을 많이 하면서 설계와 개발 문화에 대한 고민이 많아졌다.
  • 특정 언어나 프레임워크에 묶인 책이 아니라서, 지금 쓰는 스택이 바뀌어도 남을 이야기일 것 같았다.
  • 실제로 코딩과 협업을 하다보니 기술적인 해결방법은 정답이 있어 오히려 쉽게 찾을 수 있는데, 사람들과 어떤 제품을 만들면 여러 애로사항이나 병목이 생기고 그걸 헤쳐나가는 인사이트가 필요했다.

그리고 첫 장을 읽자마자 나는 바로 밑줄을 그을 수밖에 없었다.

실용주의 프로그래머의 첫 밑줄

문제를 더 큰 맥락에 놓고 더 큰 그림을 보려고 노력한다.

실용주의 프로그래머는 책임감이 있기 때문에 프로젝트가 방치된 채로 끝장나는 걸 가만히 옆에 앉아서 지켜보고만 있지 않는다.

이렇게 읽으라는데

보통 책은 목차 순서대로 읽기 마련이다. 그런데 이 책은 큰 틀을 장으로 나누고, 그 안의 내용을 토픽(topic) 단위로 분류한다.

토픽은 순서와 상관없이 읽어도 된다. 실제로 책도 그렇게 쓰여 있다. "이건 후반부에서 다룰 것이다"라며 말을 끊고, 앞뒤를 왔다 갔다 하면서 설명한다. 즉 내가 궁금한 토픽만 골라 읽어도 되고, 어려우면 넘어가도 된다.

실용주의 프로그래머의 첫 밑줄

나는 그냥 처음부터 순서대로 읽었다. 그리고 어렵거나 관심 없는 내용은 넘겼다.

솔직히 몇몇 부분은 이해가 잘 안 돼서 지루했다. 고지식한 내용이 많은 건 아닌데, 읽다 보면 이 책 그냥 허무맹랑한 이야기만 하는 건가? 싶을 때가 있었다. 계속 깨달음을 주려고 발버둥치는 문장들이 이어지는데, 내가 겪어보지 못한 상황에 대한 이야기가 나오면 끝끝내 공감하지 못하고 넘어갔다.

그래서 이 글은 책 요약이 아니다. 장별로 흥미로웠던 토픽을 두어 개씩 골라서, 내가 뭘 느꼈는지 기록하는 용도다. 복잡한 기술적 내용은 적지 않는다. 궁금하면 책을 사서 읽어보길 권한다.

그럼 시작한다.


1장 실용주의 철학

고양이가 내 소스 코드를 삼켰어요.

실용주의 철학의 초석 중 하나는 자신과 자신의 행동에 대해 책임을 지는 것이다.

즉, 여기서 말하는 책임은 신뢰와 비례한다. 요즘 AI slop이라고 말을하하는데, 오류나 코드에 대한 질문을 하면 'AI가 해서 잘 모른다'라는 식으로 답변을 하는 사람이 많아졌다. 나 역시도 스스로 검토하지 못한 부분이 있다면 창피한 변명을 하기도 한다. 이런 행동은 확실히 신뢰를 떨어트리고 책임감이 정말 없어보인다.

신뢰에 구멍이 뚫리면 원상복구가 어렵다. 그래서 최대한 팀원들에게 신뢰를 주기위해서 내가 작성한 코드와 머지한 코드는 내가 책임지고, 설명할 수 있게 노력한다.

AI가 작성한 방대한 양은 인간이 단기간에 검토하기 어렵기도 하고, 자꾸 스스로 인지했다고 착각하게 만든다. 결과물이 제대로 나오니 그냥 스스로 이 코드를 이해했다고 착각한다. 그래서 AI가 코드를 작성한 날은 설명을 미루고, 집가서 다시 찾아본다. 제대로 이해하며 검토한다. 정말 신기하게도 그러면 내 것이 된다. 그리고 검토하다보면 정말 이상하게 코드를 짜는 부분이 있다. 물론 10번 중 2번 정도이다. AI 너무 잘한다.

역시 이해가 병목이다. 그러기 위해서 계속 질문한다 많이 질문한다. 그렇게 하다보면 이해가 된다.

소프트웨어 엔트로피 — 깨진 창문을 내버려 두지 말라

창문이 깨진 채로 내버려두면, 금방 폐허가 된다.

맞는 말이다. 쓰레기 같은 코드를 보면 금방 고쳐야한다. 다음은 없다. 일에 치쳐서 귀찮아서 미루면, 그 다음에 고치기 더 어려워진다. 그래서 나는 생각나면 바로 고친다. 기능 개발이 끝나면 바로 리팩토링에 들어가야한다. 하지만 쉽지 않다.

그래서 기능개발하면서 조금씩 다른 부분의 영향이 끼치지 않을 정도로만 리팩토링을 한다. 이게 내 절충안이다.

그리고 왜 깨진 창문을 내버려두면 안 되는지에 대한 핵심은 다음과 같다.

쓰레기 같은 코드가 많다면, 나 역시 레거시 프로젝트를 받으면 "이거 고치고 싶다"는 생각이 들지 않는다.

이렇게 되면 쓰레기 같은 사고도 생긴다. 여기서 중요한 건 처음부터 잘 만들면 되지 않나? 라고 생각이 들 수 있는데, 코드는 음식과 같다. 그냥 처음부터 잘 만들어도 언젠간 상한다. 트렌드는 바뀌고, 사람 역시 취향도 바뀐다. 우선 돌아간다면 그 코드는 오답이 아니다.

지식 포트폴리오

지식을 자산처럼 관리하라는 이야기. 정기적으로 투자하고, 분산하고, 리스크를 감수하고, 주기적으로 재평가하라.

내가 지금 배우고 익히는 기술들은 기한 있는 자산이다. 부동산도 그렇고, 주식도 그렇다. 기술도 마찬가지다. 언젠간 사라진다.

그러면 어떡해야 하는가?

주식도 포트폴리오를 만든다. 쥑적으로 다른 투자 상품을 찾아보고 괜찮았던 투자 전략을 다시 적용한다. 기술도 마찬가지다. 새로운 프레임워크를 사용해보고 시간이 더 있다면 아예 새로운 언어를 배워보는 것도 괜찮다.

기술 서적이 아닌 책도 읽어야한다. 소프트 스킬은 정말 중요하다. 우리는 사람과 일을 한다. 기술만 잘한다고 되는게 아니다.

나는 프론트엔드로 시작했지만, 지금은 백엔드 인프라 등등 가리지 않고 다 해본다. 내가 좋아하는 것은 문제를 정의하고 해결하는 일이지. 사용자 반응과 인정에 대한 도파민이 필요한게 아니다. 그리고 정말 재밌는 건, 백엔드를 하니까 프론트엔드가 이해가 되었다. 프론트엔드를 하니까 어떤 데이터가 필요한 지 알게되었고, 인프라를 하니까 프론트엔드와 백엔드가 어떤 데이터를 주고받는지 이해가 되었다.

이건 내 개인적인 생각이지만, 개발자들이 편식을 하지 않았으면 좋겠다. 앞으로 AI 시대는 이 간극을 좁혀준다. 그런데도 나는 이 기술만 파보겠다고 이야기하는 건 스스로가 도태되겠다고 말하는 것과 다름이 없다. 참 아쉽다.

2장 실용주의 접근법

소통하라 !

한국어든 영어든 하나의 프로그래밍 언어일 뿐이다.

소통은 정말 중요하다. 단순히 프로젝트를 만들기 위한 소통도 중요하지만, 관계를 위한 소통도 굉장히 중요하다. 일부러 노력하는 부분도 있다.

소통 중에 제일 중요한 것은 역시 경청이라고 생각한다. 자기 말만하고 자기 주장만 하는 사람을 보면, 소통하기 꺼려진다. 단순히 내 의견이 묵살당해서 싫은게 아니라. 보통 그런 사람과 이야기하다보면, 그 사람은 맥락에 집중을 못 하고 갑자기 툭 자기 이야기를 하는 경향이 많기 때문이다. 그러면 원래 하려던 대화를 하려던 본질이 흐려진다. 그래서 나는 상대방의 이야기를 끝까지 듣고, 그 사람의 맥락을 이해하려고 노력한다.

그리고 이건 팁인데, 상대방이 맥을 자꾸 끊고 이야기를 한다면, 그냥 내 이야기를 하지 않는다. 굳이 상대하기 싫기 때문이다. 하지만 중요한 이야기라면 단호하게 말을 끊지 말아달라고 정중하게 요청한다.

청중을 알라

내 제품을 비개발자에게 이야기하려면 개발자는 머리를 쥐어 싸메고 아파한다. 그 이유는 비개발자에게 알기 쉽게 말을 해야하기 때문인데, 이건 개발자에게 소통할때도 동일하게 작용해야한다. 상대방이 내가 아는 기술 스택이나 내가 하려고 하는 기술적인 이야기들을 알 것 이라고 생각하는 것은 위험하다. 굳이 쉽게 이야기하면 되는 것을 어렵게 이야기 하려는 것은 개발자의 자존심이라고 생각한다. 그냥 쉽게 이야기 하자.

그리고 무언가를 설득해야하는 상황이라면, 나쁜 이야기는 되도록이면 하지말자. 질문이 들어올 때 해야한다. 이건 숨기려고 하는게 아니고 관심이 뚝 끊긴다. 이야기가 재미없어지고, 사람의 본성은 악한 것이 있기에 나에게 단점이 되는 이야기를 시작하면 사람들은 안 좋은 것만 생각하려한다.

질문이 왔을 때 이야기해도 늦지 않다.

좋은 설계의 핵심은 ETC

ETC(Easier To Change) — 바꾸기 더 쉽게. 저자는 이게 원칙이 아니라 가치 판단의 기준이라고 말한다. 어떤 설계가 좋은지 물었을 때, "나중에 바꾸기 쉬운 쪽"을 고르라는 것.

좋은 설계는 그냥 바꾸기 쉬운 설계이다. 자신의 기술적 이기심을 통해서 어렵고 복잡하게 설계하는 사람이 있다. 이건 혼자 프로젝트 할 때만 이야기다. 팀 프로젝트에서는 이런 설계는 독이 된다.

DRY — 사실 코드 중복 이야기가 아니었다

DRY를 "같은 코드를 두 번 쓰지 마라"로 알고 있었다. 근데 책은 지식의 중복을 말한다. 코드가 똑같이 생겼어도 이유가 다르면 중복이 아니고, 코드가 달라도 같은 지식을 표현하면 중복이라는 것.

DRY 정말 중요하다. 하지만, DRY를 지키기 위해서 무리하게 코드를 합치는 건 좋지 않다. 예를 들면,

def validate_age(value):
validate_type(value, :integer)
validate_min_integer(value, 1)
def validate_quantity(value):
validate_type(value, :integer)
validate_min_integer(value, 1)

이 두개의 코드는 DRY 위반이라고 생각할 수 있다. 하지만 그건 틀렸다. 코드는 동일하지만 두 함수가 표현하는 지식은 다르다. 목적이 다르다. 이 점을 유의하자.

직교성

한 곳을 고쳤을 때 다른 곳이 안 깨지는 상태. 이건 결합도 이야기(5장)와 이어진다.

'부끄럼 쟁이 코드를 작성해라.' 이 말이 정말 와닿았다. 차라리 바꾸기 쉬운 코드를 작성하라는 것이다.

예광탄

어둠 속에서 빛을 내는 코드

코딩에서 동일한 효과를 얻으려면 우리를 요구 사항으로부터 최종 시스템의 일부 측면까지 빨리, 눈에 보이게, 반복적으로 도달하게 해 줄 무언가를 찾아야 한다.

시스템을 정의하는 중요한 요구 사항을 찾아라. 의문이 드는 부분이나 가장 위험이 커 보이는 곳을 찾아라. 이런 부분의 코드를 가장 먼저 작성하도록 개발 우선 순위를 정하자.

프로토타입과 포스트잇

프로토타이핑으로 학습하라

프로토타입은 소비자에게 보여주기 위한 것이라면, 프로토타이핑은 그냥 구글 docs에 내가 생각한 기능들을 정리하는 것이다. 이것을 통해서 학습하는 것이다. 이건 코드를 작하하는 것이 아니다.

그리고 프로토타입을 만들 때는 속도가 중요하다. 이건 검증단계이기때문에 복잡한 예외케이스를 둘 필요가 없다.

3장 기본 도구

파워 에디팅

에디터를 유창하게 쓸 수 있게 하라.

요즘 AI로 개발을 하더라도 개발자는 코드를 보고 수정할 줄 알아야한다. IDE를 잘 쓰는 것이 중요하다. 화면 분할에 단축키를 모르는 개발자는 없어야 하며, 자신에게 맞는 커스텀 매핑키는 필요하다고 생각한다. (물론 이건 개인차가 있다.)

이 토픽을 읽고 나는 바로 터미널과 에디터를 cmd+;를 하면 포커스를 이동할 수 있게 만들었다. 요즘은 터미널에서 에이전트 명령을 많이 하기 때문이다. 이렇게 하면 개발 생산성이 올라갈 것이다.

이렇듯 지금 내가 불필요하게 움직이고 있던 행동이 있다면, 효율적으로 움직일 수 있게 만들어야한다.

디버깅

특정한 증상만 고치려고 하지 말고, 항상 문제의 근본 원인을 찾으려고 노력하라.

요즘 간단한 버그는 AI로 해결이 가능하다. 하지만 본인이 재현하기도전에 에러 스택 트레이스를 긁고 이거 '에러 해결해줘' 라고 한다면, 반성해야 한다.

본인의 눈으로 재현을 꼭 해야한다. 그리고 생각하자. 어디가 문제고 이 문제가 왜 일어났고 이걸 고치면 어떤 사이드 이펙트가 생길지 알아야한다.

AI는 동시성과 인터렉션에 대한 이해가 부족하다. 또한 우리는 성장해야하지 않는가? meat proxy가 되지 말자.

엔지니어링 일지

작업하면서 보고 배운 걸 종이 일지에 적으라는 토픽. 읽으면서 "이거 내가 블로그로 하고 있는 거네" 싶었다.

그리고 나는 노트에 그냥 내 생각들을 적고 그냥 AI가 내뱉은 말도 적는다. 그래야 내가 궁금한게 무엇인지 바로 알 수 있다.

4장 실용주의 편집증

죽은 프로그램은 거짓말을 하지 않는다

에러를 삼키지 말고 일찍 죽으라는 이야기. try/catch로 감싸서 조용히 넘기는 코드가 제일 위험하다.

로그라도 심어 놓든가. 멈추게 하자.

헤드라이트를 앞서가지 말라

헤드라이트가 비추는 거리보다 멀리 있는 건 계획하지 말라는 것. 작은 단계로 가고, 다음 단계가 안 보이면 멈추라는 이야기.

언제나 신중하게 작은 단계들을 밟아야한다. 너무 큰 작업은 '예언'을 해야하는 모든 작업이다.

이렇게 예언하면서 코드를 작성하면 미래에는 비명을 지르게 되는 것 같다.

즉, 헤드라이트가 비추는 곳 까지만 코드를 작성하자.

  • 변경이 쉽게 가능한 코드
  • 결합도가 낮고, 응집도가 높은 코드
  • 네이밍이 직관적
  • 함수의 책임이 너무 많지 않은 것

5장 구부러지거나 부러지거나

결합도 줄이기 — 묻지 말고 말하라

객체 내부를 파고들어 상태를 꺼내 쓰지 말고, 하고 싶은 일을 시키라는 이야기.

'열차 사고'를 조심해야한다.

public vodie applyDiscount(customer, order_id, discount){
customer
.orders
.find(order_id)
.getTotal()
.applyDiscount(discount)
}

이건 최상위 계층이 모든 것을 알고 있는 코드다. 작성할 때는 쉽게 작성이 되지만, 유지보수는 최악이다.

public vodie applyDiscount(customer, order_id, discount){
customer
.FindOrder(order_id)
.applyDiscount(discount)
}

이런식으로 줄여보는 건 어떤가? 이건 최상위 계층이 모든 것을 알 필요가 없다.

상속세

상속은 비싸다. 상속세를 내야한다.

상속을 코드 재사용 수단으로 쓰지 말라는 이야기다. 부모 클래스 하나 고치면 자식이 전부 흔들린다. 상속 트리가 깊어질수록 이 비용은 복리로 붙는다. 그래서 상속세다.

나도 예전엔 공통 로직이 보이면 일단 부모로 올렸다. 지금은 웬만하면 합성으로 간다. 필요한 걸 넣어주는 쪽이 나중에 빼기도 쉽다.

프론트엔드 컴포넌트도 똑같다. 비슷한 컴포넌트가 생겼다고 상위 컴포넌트를 만들어서 상속 구조처럼 쌓으면, 나중에 하나만 다르게 동작해야 할 때 isXXX 같은 플래그가 붙기 시작한다. 그 플래그가 세 개쯤 되면 그 컴포넌트는 이미 아무도 못 고친다.

6장 동시성

시간적 결합 깨트리기

시간적 결합은 순서에 대한 결합이다.

이 토픽은 비동기에 대한 이해가 없으면 그냥 흘러간다. 반대로 비동기를 확실히 이해하고 보면 훨씬 잘 읽힌다.

핵심은 이거다. 내 코드가 순차적인 이유가 "순서가 필요해서"인지, 아니면 "그냥 그렇게 썼기 때문"인지를 구분하라는 것.

const user = await getUser(id);
const posts = await getPosts(id);
const config = await getConfig();

이 코드는 세 줄 다 서로를 기다린다. 그런데 실제로 서로가 필요한가? getConfig는 앞의 둘과 아무 상관이 없다. 그냥 위에서 아래로 쓰다 보니 줄을 선 것이다. 이게 시간적 결합이다.

const [user, posts, config] = await Promise.all([
getUser(id),
getPosts(id),
getConfig(),
]);

책은 이걸 활동 다이어그램으로 그려보라고 한다. 그려보면 병렬로 갈 수 있는 구간이 눈에 보인다. 나는 다이어그램까지 그리진 않지만, await가 세 줄 이상 연달아 나오면 한 번은 의심한다.

그리고 이건 코드에만 해당되는 이야기가 아니다. 일도 마찬가지다. 디자인이 나와야 개발을 시작할 수 있다고 생각했는데, 사실 API 스펙부터 잡으면 병렬로 갈 수 있었던 적이 많았다.

공유 상태는 틀린 상태

공유 상태는 틀린 상태다.

여러 곳에서 같은 상태를 만지는 순간 문제가 시작된다.

책에 나오는 예시가 좋다. 냉장고에 우유가 없는 걸 확인하고 마트에 갔는데, 그 사이에 룸메이트도 냉장고를 확인하고 우유를 사 왔다. 냉장고에 우유가 두 개다.

문제는 "확인"과 "행동" 사이에 틈이 있다는 것이다. 확인한 시점의 상태는 이미 과거다.

나도 이걸로 한 번 크게 고생했다. 요청마다 새로 만들어져야 하는 객체를 애플리케이션 전체가 공유하고 있었다. 로컬에서는 나 혼자 요청하니까 아무 문제가 없었다.

DataLoader를 매 요청마다 5개 만드는데 REQUEST scope는 안 썼다

혼자 쓸 때는 절대 안 터진다는 게 이 문제의 제일 고약한 점이다.

7장 코딩하는 동안

우연에 맡기는 프로그래밍

돌아가니까 됐다, 하고 넘어가는 코드. 왜 되는지 모르면서 되는 코드는, 왜 깨졌는지도 모른 채 깨진다.

책은 이걸 "우연에 맡기는 프로그래밍"이라고 부른다. 의도적으로 프로그래밍하라는 것이다.

이 토픽이 제일 뜨끔했다. 그리고 1장에서 했던 이야기와 정확히 이어진다.

AI가 준 코드가 돌아가면 우리는 넘어간다. 테스트도 통과하고 화면도 잘 나온다. 그런데 왜 되는지는 모른다. 이게 우연에 맡기는 프로그래밍의 가장 극단적인 형태라고 생각한다. 예전에는 스택오버플로우에서 복사해 온 코드 한 줄이었는데, 지금은 파일 열 개다.

그래서 나는 비판적으로 보려고 한다. 방법은 단순하다.

  • 이 코드가 없으면 어떻게 되는지 한 번 지워본다.
  • 이 조건문이 왜 있는지 설명할 수 있는지 스스로 물어본다.
  • 설명이 안 되면 그건 아직 내 코드가 아니다.

책에서는 "가정하지 말고 증명하라"고 한다. 돌아가는 걸 확인하는 것과 왜 돌아가는지 아는 것은 완전히 다른 이야기다.

이름 짓기

이름은 그 코드가 무엇인지가 아니라 왜 존재하는지를 담아야 한다는 이야기.

요즘 나는 이름 짓기에서 딜레마가 하나 생겼다. 사람이 읽기 좋은 이름과 AI가 읽기 좋은 이름은 같은가?

AI는 맥락을 이름에서 많이 가져간다. 그래서 서술적이고 긴 이름을 좋아한다. 반대로 사람은 도메인 맥락을 이미 알고 있으니까 짧은 이름을 선호한다. 팀에서 매일 쓰는 단어라면 세 글자로 충분하다.

한동안 고민했는데, 결론은 둘이 싸우는 게 아니었다. 책이 말하는 기준이 그대로 답이었다. 왜 존재하는지를 담으면 사람도 AI도 잘 읽는다. data, handleClick, utils 같은 이름이 문제인 거지 짧은 이름이 문제가 아니다.

다만 AI가 잘 읽으라고 이름을 장황하게 만드는 건 반대다. 그건 코드가 아니라 프롬프트다. 맥락은 이름이 아니라 문서나 규칙 파일에 넣으면 된다.

8~9장 프로젝트

이 두 장은 요즘 프로젝트를 만들면서 도움이 되는 부분이 많았다.

요구 사항의 구렁텅이

요구 사항은 아키텍처가 아니다. 요구 사항은 설계가 아니다. 요구 사항은 사용자 인터페이스가 아니다. 요구 사항은 필요다.

이 문장에 밑줄을 그었다.

기획이 "여기에 버튼을 하나 넣어주세요"라고 하면 그건 요구 사항이 아니다. 이미 해결책이다. 진짜 요구 사항은 그 버튼으로 뭘 하고 싶은지에 있다.

그래서 나는 계속 묻는다. 왜 필요한지, 지금은 어떻게 하고 있는지, 안 되면 무슨 일이 생기는지. 물어보면 버튼이 아니라 다른 게 답인 경우가 꽤 있다.

불가능한 퍼즐 풀기

생각의 틀을 벗어나지 말고, 진짜 틀을 찾아라.

이 토픽이 재밌었다. 보통 "틀을 깨라"고 하는데 책은 반대로 말한다. 사람들이 못 푸는 이유는 틀 안에 갇혀서가 아니라, 진짜 제약이 무엇인지 모른 채 스스로 없는 제약을 만들어서라는 것이다.

막힐 때 나는 이렇게 한다. 지금 못 하고 있다고 생각하는 이유를 전부 적는다. 그리고 하나씩 묻는다. 이거 진짜 못 하는 건가, 아니면 내가 안 된다고 생각하는 건가.

의외로 절반은 후자다. 자신만의 방법에서 빠져나오는 게 먼저다.

함께 일하기

짝 프로그래밍과 몹 프로그래밍.

읽으면서 바로 든 생각은 "이거 지금 AI랑 하고 있는 거네"였다.

책은 짝 프로그래밍에서 역할이 나뉜다고 말한다. 키보드를 잡은 사람은 문법이나 코딩 스타일 같은 낮은 수준의 세부 사항에 집중하고, 옆에서 보는 사람은 문제를 더 높은 수준에서 넓게 본다.

지금 내가 에이전트와 일하는 방식이 정확히 이 구조다. 입력은 AI가 하고, 나는 더 넓은 범위를 본다.

그런데 여기서 조심할 게 있다. 짝 프로그래밍에서 두 사람은 언제든 역할을 바꾼다. AI와 일할 때는 역할이 고정된다. 계속 위에서만 보다 보면 낮은 수준의 세부 사항을 보는 감각이 무뎌진다. 그래서 나는 가끔 일부러 내가 키보드를 잡는다.

사용자를 기쁘게 하라

사용자의 요구 사항을 충족시키는 것으로 끝내지 말고, 사용자를 기쁘게 하라.

개발자의 성과는 코드가 아니라 사용자에게 남은 것으로 측정된다는 이야기다.

맞는 말인데, 나는 여기서 한 번 걸렸다. 기쁘게 하려면 사용자가 뭘 원하는지 알아야 하는데, 그건 결국 위의 요구 사항 이야기로 돌아간다. 결국 다 이어져 있다.


읽고 나서

이 책을 읽으면서 공감한 토픽과 끝내 공감하지 못한 토픽이 명확하게 갈렸다. 그 차이는 결국 경험의 유무였다. 겪어본 이야기는 밑줄을 그었고, 안 겪어본 이야기는 아무리 읽어도 안 들어왔다.

그래서 이 책은 한 번 읽고 끝낼 책이 아닌 것 같다. 몇 년 뒤에 다시 펴면 그때 넘겼던 토픽에 밑줄을 긋게 될 것이다. 토픽 단위로 나눠 놓은 것도 그래서인 것 같다. 순서대로 읽을 필요가 없다는 말은 사실이었다. 다음엔 목차에서 골라 읽을 생각이다.

그리고 이 책은 답을 주는 책이 아니었다. 판단 기준을 주는 책이었다. 나한테 남은 건 결국 한 줄이다.

바꾸기 더 쉬운 쪽을 골라라.