이 책에서는 어떻게 하면 소프트웨어 개발을 더 잘 할 수 있는지에 대해 말하고 있다. 가장 먼저는 마음가짐으로 시작해서(이 외에도 여러 책에서 마음가짐에 대해서 언급하고 있는데, 그만큼 마음가짐이 중요하다는 뜻인 것 같다), 그외에도 지켜야할 여러 가지 원칙들, 저자의 경험에서 비롯된 팁(?)과 생각들에 대해서도 언급하고 있다. 코드는 한줄도 나오지 않지만 이야기만으로도 가치가 있다고 느껴진다. 물론, 아직 본인은 현업에서 몸을 담은 시간이 거의 없다시피 하기에, 공감하기 힘든 부분도 조금 있었지만 머리속에 좋은 소프트웨어를 만들기 위해서 갖고 있어야 할 소양에 대한 '인식'을 심는데에는 충분했던 것 같다.
각각의 챕터가 독립적이기 때문에 짧은 호흡으로 읽을 수 있다는 것도 좋았다. 특히 테스트(E2E, 통합, 단위)에 대해서 언급해준 부분이 좋았으며(아무래도 난 아직은 절대적으로 지식이 많이 필요한가보다. 부족한 지식을 채워주는 느낌), '관찰 주기' 등 그 외에 다루고 있는 주제들은 모두 프로그래머라면 한번쯤은 생각해보면 좋은, 흥미로운 것들에 대해 이야기하고 있다. 내용 자체가 무겁지 않아 가볍게 읽어보기 좋으며, 그렇다고 영양가가 없는 것도 아니었다. 읽어보고 스스로 고민하는 시간을 가져본다면 좀 더 나은 프로그래머로 나아가는 데 도움이 되리라 생각한다. 아래에서도 나오겠지만, "'컴퓨터 프로그래머'는 '목수'처럼 직업이 아니라 기술이다."라는 문구가 기억에 남는다. 그래서 끊임없이 스스로를 갈고 닦아야 하는거 아닐까?
이번에도 역시 좋은 문구들을 꽤 많이(?) 추려봤다. 어디까지나 주관적이긴 하지만.
뛰어난 프로그래머가 되고자 하는 마음이 있어야만 뛰어난 프로그래머가 될 수 있다. 이런 마음이 없는 사람은 아무리 훈련을 받아도 뛰어난 프로그래머가 될 수 없다.
자신이 하는 일을 잘 이해할수록 그 일을 더 잘한다. ...(중략) 뛰어난 프로그래머가 되고 싶다면 자신이 하는 일을 제대로 이해하라.
소프트웨어 설계의 기본 원칙은 다음 두 문장으로 추릴 수 있다.
1. 구현에 드는 수고보다 유지 보수에 드는 수고를 줄이는 게 더 중요하다.
2. 유지 보수에 드는 수고는 시스템의 복잡성에 비례한다.이게 전부라 해도 과언이 아니다.
일단 공개했다면 제발 API를 망가뜨리지 마라.
유용하고 중요한 새 기능을 추가하고자 할 때 하위 호환성이 길을 막으려 한다면 그때만큼은 하위 호환성을 무시해도 된다.
복잡성은 감옥이고 단순성은 자유다.
미래를 고려하지 않으면 코드가 엉망으로 설계되고 너무 복잡해진다. ...(중략) 엄격한 설계 없이 시작한 프로젝트가 계속 성장하면 결국 개발자의 능력을 벗어날 정도로 복잡해진다. 처음부터 모든 걸 포괄하는 거대한 설계를 완성해야 한다는 뜻은 아니다. 장래에 필요한 모든 것을 예측하고 적용해야 한다는 의미도 아니다. ...(중략) 이해할 수 있고 유지 보수도 가능한, 단순한 시스템을 만들어야 한다는 뜻이다.
변화가 생겨도 쉽게 업데이트할 수 있도록 시스템을 최대한 단순하게 유지하는 게 최선이다. 목표를 '유연하게' 혹은 '포괄적으로'처럼 추상적으로 잡지 말고 '쉽게 이해하고 수정할 수 있게'처럼 구체적으로 잡아야 한다.
변화를 완전히 피할 수 없다. 하지만 소프트웨어를 바보 같을 정도로 단순화해두면 수정해야 할 일도 줄어든다.
엄격한 애플리케이션일수록 더 단순하게 작성할 수 있다.
둘은 너무 많다. ...(중략) 반복하지 마라.
통합하면 안 되는 것을 통합하지 않는 것도 중요하다.
버그는 보통 복잡성을 줄이지 못할 때 발생한다. 또 그보다는 드물지만 간단한 대상을 잘못 이해했을 때도 발생한다. ...(중략) 코드가 단순할수록 버그가 줄어들 것이다. 프로그램의 모든 것이 단순해지도록 늘 노력하라.
소프트웨어에서 가장 신경 써야 할 부분은 미래다.
개발자의 문제를 해결하고 싶다면 그 문제가 무엇인지 개발자에게 들어야 한다. ...(중략) 자기 눈에만 보이는 문제 말고 사람들이 인지하고 있는 문제를 해결하라.
'컴퓨터 프로그래머'는 '목수'처럼 직업이 아니라 기술이다.
코드 복잡성을 해결하려면 한 사람 수준의 섬세한 작업이 요구된다.
'리팩토링을 위한 리팩토링'이란 현재 작업 중인 코드와 아무 상관 없는 코드의 한 부분을 보다가 갑자기 "이 부분 설계가 마음에 들지 않는데?"라며 시스템 기능과 전혀 상관 없는 코드 일부를 이리저리 옮겨보는 걸 말한다. ...(중략) 현재 제품이나 시스템의 기능적 목표와 관련이 없는 리팩토링은 아무도 관심을 보이지 않는 쓸모 없는 물건을 정리하는 행위처럼 아무것도 성취하지 못한다.
아주 복잡한 문제를 들여다보기 시작하는 건, 마치 해변에서 바닥에 있는 모래에 닿기 위해 그 위에 쌓여 있는 돌을 치우는 것과 같다.
복잡한 코드베이스를 정리하는 핵심 원칙은 항상 기능을 위해 리팩토링하라는 것이다. ...(중략) 일단 시간이 지날수록 시스템이 더 나빠지지 않고 더 나아지는 상태로 만드는 걸 첫 번째 목표로 삼아라.
리팩토링은 제품 생산 과정에서 거치는 조직적인 절차다. 따라서 제품 생산과 신뢰할 수 있는 단순하고 빠른 방식으로 제품을 잘 생산하도록 시스템을 정리하는 일, 두 가지를 다 해야 한다. 정리를 포기하면 원하는 제품이 완성되지 않고 생산을 포기하면 리팩토링을 할 이유가 없다. 잔디에 물을 주는 건 좋은 일이다. 하지만 불부터 끄자.
소프트웨어 엔지니어링의 근간에는 인간이 있다. ...(중략) 현실에서 소프트웨어 시스템을 작성하는 건 사람이다. 읽고 수정하고 이해하는 주체도 사람이다.
컴퓨터 프로그램의 가장 중요한 세 요소가 구조(Structure), 동작(Action), 결과(Result)라고 생각한다.
소프트웨어는 지식으로 만든 단단한 실체다. 이는 지식의 모든 규칙과 법칙을 따른다. 구체적인 형태를 지니고 있다는 사실만 제외하면 거의 모든 상황에서 지식과 똑같은 양상을 보인다.
물질, 에너지, 시간이나 공간의 문제를 해결하고자 기술을 사용했을 때는 성공적인 결과를 냈다. 하지만 마음, 소통, 능력 등 인간의 문제를 해결하고자 했을 때는 실패하거나 위험한 역효과를 냈다.
소프트웨어의 보안을 보장하는 가장 중요한 요소는 단순성이다. 소프트웨어 보안의 가장 기본이 되는 질문은 "이 프로그램을 공격할 방법이 몇 가지나 될까?"이다. 그 프로그램으로 들어가는 '입구'가 몇 개냐는 뜻이다. ...(중략) 보안을 지키는 최고의 방법은 단순성을 유지하는 것이다.
소프트웨어가 성공하려면 새 버전을 출시할 때마다 꾸준히 나아지면 된다.
해결하려면 수고가 너무 많이 들 거라는 이유로 큰 문제를 방치하는 소프트웨어 프로젝트를 종종 본다. 하지만 문제의 크기를 그 문제를 방치할 핑계로 삼으면 안 된다. 오히려 장기 프로젝트 계획을 세우고 꾸준히 새 버전을 출시하며 문제를 풀어나가라는 신호로 보아야 한다.
소프트웨어 설계자가 쓰는 모든 어휘 중 가장 중요한 말은 "아니요."다.
프로그래머가 개떡 같은 이유.. 프로그래머 대다수(90퍼센트 이상)는 자신이 무슨 일을 하는지 전혀 모른다.
멍청하다는 건 자신이 모른다는 걸 모르는 것이다. 멍청한 사람들은 자신이 모르는 걸 안다고 생각하거나 더 알아야 할 게 있다는 걸 모른다.
"마감 때문에 단순한 코드를 쓰지 못한다."는 "나는 이 코드를 간단하게 작성할 만큼 빠른 프로그래머가 아니다"라고 표현할 수 있다.
생각하려고 멈추면 뭔가 문제가 있다는 뜻이다. 생각 자체가 문제라는 건 아니다. 하지만 생각은 다른 문제의 발생을 나타내는 신호다. ...(중략) 제대로 이해하고 있다면 생각하느라 멈출 필요가 없다. ...(중략) 자신이 생각하느라 작업을 멈췄다는 걸 인지하면 자신이 고민하던 그 문제를 해결하려고 하지 마라. 자신이 이해하지 못하는 부분이 무엇인지 외부적인 부분부터 확인하라. 그리고 이해하는 데 도움이 될 만한 무언가를 찾아라. ...(중략) 그냥 앉아서 생각만 하지 말고 뭔가 해야 한다. 이해에 도달할 유일한 길은 행동이다.
애플리케이션의 '핵심' 기능이 시작하기 좋은 가장 단순한 코드일 수도 있다. 핵심 코드를 어떻게 써야 할지 잘 모르겠다면 확신이 있는 부분부터 써도 된다.
개발 단계를 건너뛰면서 높은 생산성을 기대하지 마라.
많은 사람들이 생각이라는 활동은 똑똑한 사람들이 하는 거라고 말한다. ...(중략) 진짜 똑똑한 사람들은 배우고, 관찰하고, 결정하고, 행동한다. 지식을 얻으면 그 지식을 당면 과제를 해결하는 데 사용한다.
사용자의 관심은 프로그램 자체가 아니라 본인이 이루고자 하는 목표에 있다. 사용자가 자신의 목표를 완벽히 이룰 수 있게 도와주는 게 완벽한 프로그램을 만드는 길이다.
사용자 인터페이스에서 비슷한 것은 똑같이 보여야 한다. 하지만 다른 건 다르게 보여야 한다. ...(중략) 차이를 줄 때는 충분히 주는 것도 중요하다. 사람들은 작은 차이를 알아보지 못할 때가 많기 때문이다.
소프트웨어 세계에서 소프트웨어 개발자의 과제는 사용자의 문제를 해결하는 것이다. 사용자는 문제를 알려주고 개발자는 문제를 고친다. ...(중략) 각 판단은 적임자에게 맡기는 게 낫다.
소프트웨어는 언제나 장기적인 관점으로 보라.
사실 성공에 이르는 길은 혁신이 아니라 실행이다. 아이디어가 좋고 새로워봐야 별 의미가 없다. 현실 세계에서 얼마나 잘 구현하느냐가 중요하다.
진짜 훌륭한 프로그램은 사용자의 의사를 정확히 수행한다.
사용자의 명령을 정확하게 따르고, 사용자가 예상한 대로 작동하며, 사용자의 의도 전달을 막지 않는다.
사용자의 의도를 프로그램에 최대한 쉽게 전달할 수 있게 하라. ...(중략) 프로그램이 단순해질수록 점점 더 많은 사람이 그 프로그램을 훌륭하다고 생각할 것이다.