Ship It

Ship It by Jared Richardson, William Gwaltney

Ship It은 소프트웨어 개발에 관한 가이드라인을 담은 책이다. ‘도구와 인프라스트럭처’, ‘실용주의적 프로젝트 기술’, ‘예광탄 개발’, ‘일반적인 문제와 해결방법’의 네 부분으로 나뉜다.

‘도구와 인프라스트럭처’는 CVS 또는 Subversion과 같은 코드 저장소, 빌드의 자동화, 이슈 및 기능 추적, 테스트 자동화와 같은 이슈를 다루고 있다. 사실 이러한 도구들을 사용하라는 가이드라인은 흔히 들을 수 있는 이야기지만, 이 장의 마지막 가이드라인인 ‘실험하지 말아야 할 때’에서는 ‘핵심적인 기술을 기술 실험 대상으로 삼아선 안 됩니다’라는 중요한 교훈을 얘기하고 있다. 의욕에 찬 하지만, 경험은 부족한 개발자들이 흔히 하는 실수다.

‘실용주의적 프로젝트 기술’에서 소개하는 목록 사용은 오래 전부터 나나 내가 일하던 팀, 내 주변의 사람들이 실제로 활용하면서 훌륭한 습관임이 증명된 프랙티스다.

일일 회의나 모든 코드의 검토, 코드 변경 통지 등은 내겐 약간 적용하기 힘들어보이는 프랙티스들인데, 각각의 프랙티스는 나름의 장점들을 갖고 있다는 것에 동의하기 때문에 조금씩 적용해 볼 생각이다.

내가 맡고 있는 조직에 주간 회의를 적용하기 시작한지가 수개월 지났고, 현재는 어느 정도 정착이 되어가고 있다. 하지만, 어차피 작업이나 문제 관리를 위한 의사 소통이 매일 일어나는 것을 생각하면, 일일 회의는 의사소통이 예측 가능하게 일어나게 해주고, 때문에 효율적인 의사소통이 가능하게 해주리라 생각한다. (이는 주간 회의를 포함한 ‘정기적인 회의’의 장점일 것이다.) 하지만, 일일 회의를 시행하기 위해서는 주간 회의라는 익숙한 프랙티스를 포기해야 한다. 이와 같이, 어떤 프랙티스가 좋고, 현재의 프랙티스를 대체하자는 얘기는 너무나 쉽지만, 이것을 적용하기 위한 사람들의 지지를 얻고, 대체 과정의 비용을 줄이고, 실제로 잘 적용하는 것은 여러 고민과 많은 노력이 필요한 일이다.

코드 검토의 경우, 이 책에서는 변경을 포함한 모든 코드를 검토해야 한다고 나와있지만, 그보다 온화한 (덜 진보적인) 단계로, 새로운 모듈이나 프로그램, 시스템이 완성되었을 때, 코드 검토를 하는 프랙티스가 경험적으로는 상당히 좋았던 것 같다. 아마도 이를 코드 검토를 시작하는 팀의 마지노선으로 잡으면 될 것 같다. 코드 검토는, 이 책에서 얘기하는대로, 작은 단위로 할 수록 효율과 정확성이 높아지는데, 작은 단위로 리뷰하는 문화를 정착시키는 것은 또 다른 과제다.

현재 팀에는 기술 리더라고 할만한 사람들이 몇 명 있는데, 팀의 한 파트를 책임지고 있는 나도 그 중의 한명이라고 볼 수 있다. 간단하게 말해서, 기술 리더는 기술 업무와 관리 업무를 수행해야 하는데, 둘 다를 수행하는 것은, 한가지만을 수행하는 것에 비해 절대 쉬운 일은 아니다. 가장 중요한 책임 중 하나는 역시 우선 순위의 조정이다. 업무의 목록은 팀원들 각자가 결정할 수 있지만, 우선 순위의 문제는 항상 기술 리더의 책임이다. 요즘 내가 생각하고 있는 것은, 우선 순위 결정을 주간 보고나 주간 회의와 같은 과정에 자연스럽게 연결해 프로세스화 하는 것이다.

‘예광탄 개발’은 일반적인 애자일 개발과 얼마나 크게 차이가 있는지 모르겠고, 굳이 ‘예광탄 개발’이라는 이름표를 달아주어야 하는지 의문인데, 이 글에서는 설명을 생략하도록 한다.

‘일반적인 문제와 해결 방법’은 분류하기 힘든 가이드라인을 모아놓은 부분이라고 볼 수 있는데, 그 중 ‘불한당 개발자’에 대한 대처 방법을 다룬 항목이 흥미로웠다. 고삐를 채울 수 없는 불한당의 경우, ‘불한당의 행동을 문서화하고, 반항적 행동을 문제 삼아 해고해야 한다’는 것이다. 그리고, ‘대부분의 경우엔, 문서화 과정을 시작하는 것만으로도 충격받아 제자리로 돌아온다’라고 한다. 실제로도, 문제를 일으키는 팀원의 경우, 문제점을 지적당하면, 그 근거를 제시하라는 답이 돌아오기도 한다. 이에 대한 정당한 답변은 다른 사람에게 어떻게 얘기했는가, 어떤 예절 바르지 못한 행동을 했는가 등이 아니라, 잘 문서화된 작업 목록 뿐이다. 이런 수단이 악의적으로 사용되어서는 물론 안되겠지만 말이다. 한편, Jeff Atwood의 ‘Dealing With Bad Apple‘이란 글에서는 불한당 또는 Bad Apple은 팀 전체에 악영향을 미치며, 어떤 사람의 능력은 발전할 수 있어도 태도는 변하기 어렵다는 이유로, 빨리 제거하는 방법밖에 없다고 얘기하고 있다.

이 책 전체에서 드러나는 실용주의적 태도 – 어떤 프랙티스가 절대적으로 옳다고 주장하기 보다는 적합한 것을 적용해나가자는 태도 – 는 상당히 마음에 드는 편이다.

내용이나 태도 뿐만 아니라, 구성 면에서도, 하나의 가이드라인마다 마지막에 ‘어떻게 시작하면 될까요?’, ‘제대로 사용하고 있는 걸까요?’, ‘경고 신호’와 같은 섹션을 두어, 이 책에 나온 가이드라인을 실제로 행동에 옮길 수 있는 지침으로 활용하기 좋게 만들어져 있다.

번역은 따로 언급할 필요가 없을 정도로 잘 되어 있는 편이다. 최근에 출판되는 해외에서 유명한 기술 서적들은 평균적인 번역 품질이 예전보다는 많이 좋아진 것 같다.

Head First Javascript

Head First Javascript by Michael Morrison

Head First 시리즈는 따로 언급하지 않아도 너무나 유명한 입문서 시리즈다.

그동안 여러 간단한 웹 애플리케이션을 개발하면서, 불편하지 않을 정도로는 Javascript를 익히고 사용해왔기 때문에, 내게 적합한 책이라고 생각한 것은 아니었지만, Head First 시리즈의 유명세를 직접 경험해보고 싶은 마음이 강했다.

이 책을 읽고 나서, 과연 이 책에 대한 소문이 헛소문이 아님을 확인할 수 있었을 뿐만 아니라, 입문서로서의 본보기를 볼 수 있었다.

일반적인 프로그래밍 서적들은 흔히 커다란 분류 체계를 세워놓고 각각의 분류에서 세부사항을 하나씩 설명하는 방식을 취한다. 분류 체계는 물론 중요하다. 분류 체계를 이해하는 것은 그 분야 전체를 이해하는 것을 의미한다. 하지만, 어떤 분야 (이를테면, 프로그래밍 언어)에 익숙하지 않은 입문자에게는, 그러한 분류 체계(이를테면, 변수(variable), 자료형(type), 연산자(operator), 표현식(expression), 클래스(class) 등과 같은 분류)는 이해하기 어려울 뿐만 아니라 학습에 방해가 될 수도 있다.

이 책은, 먼저 목적 또는 필요를 제시하고, 그것을 충족시키기 위한 방법 (이를테면, Javascript의 문법, 라이브러리 요소)을 설명하는 방식을 취하고 있다. 이러한 방식은 입문서로 추천한 적이 있는 Essential C++과 같은 책에서도 보인 적이 있다.

또다른 중요한 요소는 방법을 설명한 후에는 이를 실제로 연습해볼 수 있도록 하는 것이다. 이 책에서는 ‘연습’이라는 중요한 단계를 건너뛰지 않도록 책에 직접 프로그램을 작성할 수 있도록 해두고 있다.

마지막 단계는, 여러가지 방식을 통해서 학습자가 학습한 내용을 여러 번 정리할 수 있도록 하여 마음 속에 새기는 과정이다.

이러한 Head First의 학습 방식 자체는 특별한 것은 아니지만, 기술 입문서에서만은 독특하다고 할 수 있을 것 같다. 그것이 바로 Head First 시리즈가 유명해진 비결일 것이다.

그리고, 한가지 언급하고 넘어가야할 점은, 상당히 낮은 선행 지식을 요구한다는 점이다. 설명 자체가 선행 지식을 거의 필요로 하지 않을 정도로 쉽게 되어있다. 적절한 비유를 사용해 이해를 도와주는 것도 인상 깊다.

한편, 이러한 입문서는 반대로, 입문자가 아닌 학습자에게는 오히려 좋지 않다. 분류 체계가 없는 것은 입문자에게는 이점이지만, 익숙한 분류 체계에 끼워맞추기만 하면 되는 학습자에게 분류 체계가 제시되지 않는 것은 오히려 학습 효율을 떨어뜨리는 것이다. 반복적인 내용도 마찬가지다. 물론, 입문자가 아닌 학습자가 Head First 시리즈를 고르는 것은 잘못된 일이다.

현재 번역되어 있는 Head First 시리즈는, 국내 출간일 순으로, Java, EJB, Servlets & JSP, Design Patterns, HTML with CSS & XHTML, Object Oriented Analysis & Design, PMP, SQL, Javascript (서명에서 Head First 생략) 로 총 9권이다. Moviemaking, Algebra, C#, Physics, Statistics이 아직 번역되지 않았고, Ajax, PHP & MySQL, Rails, Web Design등과 같은 주제로도 출간될 예정이다. C#, Statistics 같은 경우에는 아직 번역되어 나오지 않은 것이 아쉽다.

앞으로 입문서 추천을 누군가가 부탁한다면, Head First 시리즈를 강력하게 추천할 생각이다.

Prefactoring

PrefactoringPrefactoring by Ken Pugh

오랜 경험을 통해서 소프트웨어 개발에 관한 통찰을 얻은 소프트웨어 개발자라면, 자신이 얻은 교훈을 세심하게 준비된 실제 사례를 곁들여 다른 사람에게 보여주고 싶은 욕구를 한번쯤은 느꼈을 것이다. 이 책은 바로 그러한 책이다.

이 책의 제목인 Prefactoring은 자신과 다른 사람들의 경험으로부터 얻은 통찰을 소프트웨어를 개발하는 데에 사용하는 것이라고 저자는 설명한다. 그렇다면, Prefactoring이란 경험을 가진 여러 소프트웨어 개발자들이 이미 하고 있는 일이다. 단지 반짝하는 제목 이상의 뭔가가 있을까? 다음은 저자가 내세우는 3가지의 가이드라인이다.

  • Extreme Abstraction
  • Extreme Separation
  • Extreme Readability

더이상 언급이 필요없을 정도로 소프트웨어 개발에 있어서 핵심적인 가치들이라고 할 수 있다. Abstraction과 Separation은 나도 ‘프로그래머에게 필요한 능력‘이라는 글에서 언급한 적이 있다.

이 책에서 가장 읽을만한 부분은 Preface다. 이 책을 사지 않더라도 서점에 들르게 되면 서문 부분을 한번 뒤적거려볼만한 가치는 있다.

서문에서 얘기하고 있는 것 중 하나는 바로 어떤 원리나 프랙티스에 얽매이지 말고 항상 상황-문맥에 따라 트레이드 오프(trade-off)를 고려해서 판단해야한다는 것이다. 이름 있는 훌륭한 엔지니어들에게서는 항상 이러한 모습을 볼 수 있다.

One rule exists: nothing works everywhere, and hence, you must be the judge if a particular practice is appropriate for your application. You need to apply principles in context. The decison whether to use a particular principle or practice depends on the situation in which it is employed.

다른 하나는 바로 회고의 중요성이다. 회고에 대해서는 다른 글에서 좀 더 얘기하기로 하고 여기서는 말을 아껴야겠다. Norman L. Kerth의 Project Retrospectives라는 책을 추천하고 있는데, 한번 읽어봐야겠다.

이 책의 본 내용은 처음에 얘기했듯이 CD 대여점을 위한 가상의 프로젝트를 진행해 나가면서 정련된 가이드라인과 원리들을 보여주는 식으로 이루어진다. 이 가이드라인과 원리들은 하나하나 한번 읽고 넘기기 아까울 정도로 소중한 교훈들이지만, CD 대여점 프로젝트는 좀 지루한 편이다. 참고로 난 100 페이지 정도 읽고 나서는 그냥 나머지는 가이드라인만 읽고 말았다.

가이드라인 중에는 자주 들을 수 있는 것들도 있고 아닌 것들도 있는데, 그렇지 않은 것 중에 하나를 소개하자면 다음과 같은 것이 있다.

Splitters can be lumped more easily than lumpers can be split: It is easier to combine two concepts than it is to separate them.

다시 말하면, 뭉쳐있는 것을 나누는 것보다 나뉘어있는 것을 합치기가 쉽기 때문에, (고민이 된다면) 나누어놓는 쪽을 택하는 것이 좋다는 것이다.

이는 여러가지 상황에서 적용될 수 있는데, 예를 들어 어떤 인터페이스에서 발생할 수 있는 예외 (또는 에러 코드)들을 정한다고 해보자. 당연히 너무 세부적으로 나누면 복잡할 것 같다는 생각이 들기 마련이다. 어느 정도 수준으로 나누어야 할지도 애매한 경우가 있다. 어차피 미래의 필요는 예측하기 힘들다. 하지만 우리가 지금 알 수 있는 것은 미리 나누어두는 것이 좋다는 것이다. 나중에 쌓인 에러 로그를 보면서 비슷한 종류의 에러끼리 모아서 분석할 수는 있지만, 애초에 나누어놓지 않은 에러는 분석이 아예 불가능하다.

이러한 원리는 이러한 결정이 돌이키기 힘들 수록 더욱 강하게 작용한다. 분류하는 정보의 크기가 너무 커서 다시 분류하기가 힘들수록, 이미 여러 고객들과 미리 정한 인터페이스를 변경하기가 힘들수록 이러한 가이드라인이 머리 속에 떠오를 것이다.

이 책은 그리 두꺼운 책도 아니니 부록에 있는 가이드라인 모음만 쓱 훑어보는 식으로 읽어보는 것도 괜찮을 듯 하다. 하지만, Jolt Award 수상작에게 기대한만큼 만족스럽지 못한 것도 사실이다.

Dynamics of Software Development

Dynamics of Software Development by Jim McCarthy

요즈음 널리 유행하는 방법론들처럼 체계화 되어있는 것은 아니지만, 이 책은 소프트웨어 개발의 여러 부분들에 걸친 조언을 담고 있는 책이다. 그 범위는 소프트웨어 개발에서 어떤 것이 바람직한 리더쉽인가, 어떻게 팀을 만들 것인가, 고객이나 비즈니스 부문 등의 팀 외부와 어떻게 소통할 것인가, 경쟁 시장에서 어떻게 포지셔닝할 것인가,빌드와 출시, 개발 일정과 주기는 어떻게 할 것인가, 사람은 어떻게 뽑을 것인가와 같이 소프트웨어 개발 팀에 관련된 거의 모든 부문을 다루고 있다고 해도 과언이 아니다.

저자는 소프트웨어 개발팀을 생태계와 같은 것으로 보고 있다. 팀원들은 팀장의 지시에만 따르고, 미리 정해진 역할을 수행하는 것이 아니라, 팀장은 팀원에게 권한을 위임해야하며 (지식노동에 있어서 이것은 이미 황금률이다.) 팀원들은 자신의 능력이 다른 팀원들과 조화를 이루도록 역할을 진화시켜 나간다. 이러한 관점은 소프트웨어가 지식 노동의 산출물이기 때문에 무엇보다도 팀원들부터 아이디어가 자유롭게 나오고 그 중에서 최상의 아이디어가 선택되어야한다는 이유에 비롯한다.

애자일 소프트웨어 개발 프랙티스 (이를테면 XP와 같은)에서와 비슷한 주장들을 1995년에 쓰여진 이 책에서 하고 있는 것도 재미있는 점이다. (참고로, C3 프로젝트는 1996년에 시작되었고, Kent Beck이 유명한 Extreme Programming Explained를 내놓은 것은 1997년의 일이다.) 신속하게 개발주기를 반복한다든가, 알려진 상태를 유지하는 것, 고객과의 관계의 강조 등에서 그러한 것들을 엿볼 수 있다. Scrum과 같은 방법론은 1993년에 적용되기 시작했고, Iterative and Incremental Development: A Brief History와 같은 문서를 보면, 1980년대에 이미 점진적인 개발 방법이 소프트웨어 개발계에 떠들썩하게 떠오르고 있음을 할 수 있다.

설령 책이 제시하는 세부적인 방법들에 동의를 하지 않는다고 하더라도 한번이라도 팀에서 소프트웨어 개발을 해본 경험이 있다면, 지난 날의 경험을 회상하며 이 책의 조언에 대해 깊히 생각해보는 것은 매우 유익한 일일 것이다. 다만, 저자는 인문학적인 배경이 있는지 몰라도 문학이나 철학에 기원한 개념들을 자주 빌려쓰고 있을 뿐만 아니라 전체적인 문체도 간명한 편은 아니어서, 읽기가 쉽지 않은 면이 있다. 단지 번역의 탓만은 아닌 듯 보인다. 반대로 이러한 점 때문에, 한문장 한문장을 곱씹어볼 경우 여러가지 경우에 여러 의미로 다가올 수도 있을 것이고, 비단 저자의 조언을 곧이곧대로 받아들이기보다는 풍부한 고민의 원천이 될 수 있는 면도 있을 것이다.

Problems of Political Philosophy, Chapter 1, Section 2

제1장 ‘정치철학이란 무엇인가?’의 제2절 ‘신념에 대한 비판적 평가’의 요약입니다.

신념의 정당화

전통적인 철학의 근본적 목적은 바로 신념들을 받아들이거나 거부할 수 있는 합리적인 근거를 제공하려는 시도이다. 과학은 설명을 추구하고 인과적 설명의 형태를 띄나, 철학은 정당화를 추구하고 신념에 필요한 합리적 근거를 탐구한다.

따라서, 철학의 역할은,

  • 충돌하는 두 신념 사이의 어디에 양립불가성이 존재하는지 보여주기 위해서, 두 신념의 체계에 깔려있는 의미를 명료하게 밝히려고 노력하고,
  • 양립불가성을 해결할 방도를 제시하는 것이다.

양립불가성을 해결하는 방법에는, 전통적인 신념을 제거하거나 반대로 새로운 신념을 거부하는 방법이 있고, 2개의 신념 체계 중 하나를, 이들이 양립할 수 있도록 수정하는 있다. 이러한 작업에는 관련된 모든 사실에 알맞는 관념의 새로운 틀을 제시하는 작업이 뒤따를 수 있다. 또한, 하나의 문제가 새로운 개념적 틀이나 철학 체계를 통해 해결되면 철학자들의 관심을 그 체계 자체에로 전환하기 쉽다.

지식 철학과 실천 철학

지식 철학(인식론, 형이상학)이 무엇이 참인가에 대한 신념에 관심이 있다면, 실천 철학(도덕 철학, 사회 철학, 정치 철학)은 인간과 사회를 위해 무엇이 옳으며 선한지에 관한 신념과 원리에 관심이 있다.

비판적인 평가

신념이 합리적으로 정당화되기 위한 2가지 기준은 (내적인) 일관성사실과의 일치다.

사실의 문제(matter of fact)에 관한 신념의 경우, 즉 사실 철학의 문제에서, 일관성을 가진다고 하더라도, 실제 사실의 세계에 적용되거나 또는 일치하는지를 알아야 한다. 이 때, 철학자는 일관성을 검증할 수 있으나 무엇이 관련된 사실인가를 알아내는 것은 바로 과학의 임무다. 따라서, 지식 철학은 한 신념이 사실과 일치하는 지를 결정할 수 없다.
실천 철학은 사실과의 일치라는 기준을 대신하는 것이 무엇인지 분명하지 않다. 상충하는 가치체계 중 어느 것이 사실적, 객관적인 것으로 간주될 수 있는지 결정하기 위한 인정된 절차는 없다. 대안은 비판적인 평가에 있다. 비판적인 평가란, 한 신념을 직접적으로 정당화하는 것이 아니라, 그 신념에 대한 다른 대안을 제거함으로써 간접적으로 그것을 지지하는 형식을 말한다.

정치철학에 국한해서 실천철학에 대한 비판에 대한 반론은 다음과 같다.

  • 일관성이라는 기준이 부정적 검증으로서 어느 정도 결정적일 수 있음을 과소평가 (과학에서도 마찬가지.)

  • 전통적인 정치 철학에 대한 비판은 사실이 가치 판단을 뒷받침하는 역할을 수행한다는 점을 간과 (가치 판단은 종종 일치성의 시험을 받는 사실에 관한 신념을 전제한다.)

비판적인 평가의 문제점

정치철학에 있어서 비판적인 평가의 대상이 되는 모든 문제가 이 같은 방식으로 해결될 수는 없다. 갈등이 일어나는 대립적 주장을 살펴봄으로써, 불일치성이나 잘못된 실제적 전체들을 밝혀내는 철학적 방법은, 비교상의 가치(comparative value)에 대한 견해의 차이(e.g. 자유와 평등이라는 가치에 대한 서로 다른 상대적인 평가)라는 핵심적인 문제를 미해결된 상태대로 내버려두는 문제점을 가지고 있다.

소프트웨어 공학의 사실과 오해 Facts and Fallacies of Software Engineering

우리가 미처 알지 못한 소프트웨어 공학의 사실과 오해우리가 미처 알지 못한 소프트웨어 공학의 사실과 오해, by Robert L. Glass

Robert Glass의 이 책은 내가 읽은 소프트웨어 엔지니어링에 관한 문헌들에서 자주 인용되기에 꼭 한번 읽어봐야지 하고 생각하고 있던 책이다.

제목 그대로 이 책은 소프트웨어 엔지니어링에 관한 사실들과 오해들을 열거하고, 각각에 관한 논쟁과 저자의 의견들을 정리해놓은 책이다. 각각의 항목들은 다른 유명한 저작들에서 언급된 내용이 많아서 ‘집대성’의 느낌이 든다. 이 책의 가장 큰 목적은 저자가 서론에 언급한대로 ‘기본적이면서도 중요’한 사실들인데도 ‘자주 잊혀지’는 사실들을 사람들이 ‘반복해서 배우게’하는 것일 것이다. 한편으로는 사실들의 원저작에 해당하는 개개의 저작들을 읽을 때와는 다르게, 여러 사실들과 논쟁을 한곳에 정리해놓음으로써, 소프트웨어 엔지니어링에 대한 생각을 정리하고 관점을 만들어낼 수 있도록 도와준다.

대부분의 사실들은 말그대로 ‘사실’로 통용되는 것들이지만, 몇몇은 아직 논쟁거리인 경우도 있고, 개인적으로 동의하고 싶지 않거나 또는 그동안 믿지 않았던 것들도 있었다. 사실 이러한 점들을 읽는 도중에 메모를 해서 정리했어야 하는데, 그러지 못한 것이 후회된다. 하지만, 이 책은 한번 더 읽어볼 기회가 있을 듯하고, 그 때는 반드시 그에 관한 글을 따로 써야겠다.

저자가 채택한 사실에서 몇가지 경향을 찾아본다면, 다음과 같다.

  • 사람이 중요하고 도구와 기술은 그보다 중요하지 않다.
  • 어떤 문제에서든 은탄환은 없다.
  • 소프트웨어 개발 프로세스의 초기 단계들(요구사항, 설계)은 중요하다.
  • 소프트웨어 개발 프로세스의 몇몇 단계들은(테스팅, 검토, 유지보수)은 대단히 중요하지만 과소평가되고 있다.
  • 대규모 또는 범용적인 재사용은 어렵다.

저자는 소프트웨어 엔지니어링 학계에서 널리 받아들여지고 있는 사실들은 단정적으로 받아들이고 있으며, 소프트웨어 엔지니어링에 있어서의 최근의 변화에 대해서는 어느 정도 긍정적인 점들은 인정하기는 하나 약간 망설이는 느낌이 든다. 한마디로 말해 보수적이다. 어떻게 보면, 학계가 바라보는 현재의 소프트웨어 엔지니어링에 대한 시점이 이 책에 그대로 반영되어있다는 느낌이 든다. (이를테면, 학계에서도 인정이 되고 있는 패턴에 대해서는 항목을 하나 할애해서 재사용에 대한 해법 중 하나로 인정하고 있다. 반면 오픈소스나 XP에 대해서는 약간 방어적이다.)

하지만, 그러한 태도가 이 책의 단점이라기보다는 장점이라고 생각한다. 소프트웨어 엔지니어로서 우리는 새로운 기술, 도구, 프랙티스가 우월하므로 도입해야만 한다는 강박관념에 항상 시달려왔다.  우린 오히려 좀 더 신중해야할 필요가 있다.

이 책을 읽으면서 자꾸만 내가 겪었던 현실들이 떠오르면서 나 또는 다른 사람들이 기본적이면서도 중요한 사실들을 얼마나 자주 잊고 있는가를 되돌아보게 되었다. 저자에게 동의하지 않을 수 없는 것은 이러한 사실들은 정말로 반복해서 배우는 수밖에 없을 것이라는 점이다.

Refactoring: Improving the Design of Existing Code

Refactoring: Improving the Design of Existing CodeRefactoring: Improving the Design of Existing Code, by Martin Fowler

리팩토링이 없다면, 소프트웨어의 생명 주기가 진행될 수록 소프트웨어의 질은 점점 떨어질 수 밖에 없다. 현대적인 관점에서 소프트웨어 개발은 더이상 Rocket Science처럼 고정된 결과물을 산출하는 활동이 아니다. 뛰어난 소프트웨어 아키텍트라 하더라도 소프트웨어 개발 프로젝트의 초기에 그 소프트웨어를 바라보는 방식 (또는 디자인)이 후반에까지 변함없이 지속될 확률은 매우 낮다. 하물며 여러 사람이 함께 일하는 팀 소프트웨어 개발에서야 더이상 말할 것도 없다. 특히, 사용자의 요구사항이 다 떨어져서 더이상 변경할 것이 없어지지 않는 한, 소프트웨어 질의 하락은 점점 빨라질 뿐이다.

이 책은 리팩토링에 관한 바이블이다. Martin Fowler는 더이상 언급할 필요도 없는 유명한 저자다. 이 책은 리팩토링과정 예시를 통한 리팩토링에 관한 소개, 리팩토링의 정의와 중요성, 리팩토링을 언제, 어떻게 적용할 것인가에 관한 가이드, 리팩토링 패턴 카탈로그로 이루어져 있고, 리팩토링의 간략한 역사와 리팩토링의 도입 방법, 리팩토링도구에 관한 의미있는 에세이들으로 끝맺고 있다.

Martin Fowler는 리팩토링을 다음과 같이 정의하고 있다.

Refactoring: a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.

리팩토링의 목적은 소프트웨어를 좀 더 이해하게 쉽게 만들거나 그 과정에서 소프트웨어를 좀 더 이해함으로써 소프트웨어를 수정하는 비용을 줄이는 것이다. 반대로 말하면, 소프트웨어를 수정할 필요가 없다면, 리팩토링을 할 필요는 없다는 얘기가 된다. 또한 여기에는 한가지 가정이 있는데, 소프트웨어를 좀 더 이해하기 쉽다면, 수정하기도 쉽다는 것이다. 당연한 얘기같지만, 많은 개발자들은 어떤 이유에서건 이를 중요하게 생각하지 않는다.

리팩토링의 정의는 리팩토링의 가장 중요한 측면 또한 언급하고 있는데, 바로 겉으로 드러나는 소프트웨어의 동작 방식을 변경하지 않는다는 것이다. 리팩토링 패턴 카탈로그는 바로, 소프트웨어의 동작 방식을 변경하지 않는다는 제약을 위해서 어떤 방식으로 Refactoring을 수행해야하는가에 관한 패턴들을 모아둔 것이라고 볼 수 있다. 그리고, 이러한 제약을 보장하기 위해서 Unit Testing을 제안하고 있는 것이다.

패턴 카탈로그를 읽는 것은 (항상 그렇듯이) 매우 지루한 일이었다. 패턴 카탈로그는 패턴이 갖는 이점들을 제공하지만, 카탈로그를 처음부터 끝까지 읽어볼 정도로 가치가 있지는 않다. 특히, Mechanics 부분은 읽지 않아도 무방하다. 어느 정도 숙련된 개발자라면 리팩토링의 개념만 잘 알고 있다면, Mechanics를 직접 읽어볼 필요 없이 같은 것을 수행할 수 있을 것이다. 특히, 많은 수의 리팩토링 패턴들이 도구를 통해 자동화가 되어있는 현재 시점에서는 더더욱 그러하다. 내가 추천하는 방법은, 패턴의 이름(Name), 맥락(Context) 부분과 동기(Motivation) 부분만 읽고, 이해가 가지 않는 경우에만 예시(Example) 부분을 읽어보는 것이다. 내게는 패턴들을 통해 어휘를 확장시킬 수 있었던 것이 가장 큰 도움이 되었다. 예를 들어, 실제로 리팩토링을 수행할 때, 커밋 로그(Commit Log)에 리팩토링 패턴을 적어넣을 수 있어서 편리했다. 사실, 만약 이 책을 가장 효과적으로 읽고 싶다면, 패턴 카탈로그만 빼고 다 읽고 나서, 패턴 카탈로그들은 이름만 익숙해질 정도로만 훑어보라고 조언해주고 싶다.

패턴 카탈로그 읽는 것을 마치고 수십 페이지 남겨놓은 상태에서는, 마치 이미 이 책을 다 읽었다는 듯 생각을 하고 있었는데, 이 책의 마지막 장들에 들어있는 에세이들은 상당히 중요한 문제 제기와 인식을 제공해주었다.

사실상 리팩토링이라는 단어를 처음으로 만들고 초기부터 연구를 수행한 William Opdyke의 에세이는, 왜 실제 세계에서 프로그래머들은 리팩토링을 하지 않으려하는가를 따져보고, 어떻게 하면 그런 문제를 넘어 리팩토링을 적용할 수 있을 것인가에 관해서 얘기하고 있다. 자세히 설명하기 보다는 다음 문단을 인용하도록 하자.

Within Lucent/Bell Labs I found that encouraging application of reuse and platforms required reaching a variety of stakeholders. It required formulating strategy with executives, organizing leadership team meetings among middle managers, consulting with development projects, and publicizing the benefits of these technologies to broad research and development audiences through seminars and publications. Throughout it was important to train staff in the principles, address near-term benefits, provide ways to reduce overhead, and address how these techniques could be introduced safely. I had gained these insights from my refactoring research.

이 내용은 비단 리팩토링에만 해당되는 것은 아니다. 주로 단기적인 성과를 중요시하는 기업 환경에서, 장기적인 투자를 필요로 하는 무언가를 추구하기 위해서는 위에서 언급한 모든 일들을 할 수 있을 정도로 부단히 노력해야한다는 생각이 든다.

두번째 에세이는 리팩토링 도구에 관한 얘기를 하고 있는데, 이 책이 쓰여진 1999년에는 어느 정도 널리 퍼진 리팩토링 도구가 없었겠지만, 2007년 현재에는 주요 언어인 Java의 주요 IDE들이 리팩토링을 직접 지원하고 있기 때문에, 기술의 변화를 지면을 통해 느낄 수 있게 해준다.

이 책의 마무리에 해당하는 Kent Beck의 에세이는 리팩토링을 할 때 가져야할 마음가짐에 관해서 얘기하고 있는데, 중요한 항목들은 여기에 인용할 가치가 있을 것이다.

  • Get used to picking a goal
  • Stop when you are unsure
  • Backtrack
  • Duets

이 책을 읽기 시작하면서 바로 떠오른 생각은 패턴들로 리팩토링하는 리팩토링 패턴이 이 책에는 별로 없다는 것이다. 저자는 이 책에서 리팩토링 패턴의 가장 작은 단위들을 우선적으로 다루고 싶어했고, 그 목적은 의미가 있었던 것 같다. 그리고 이 책에서도 같은 아이디어를 여러번 언급하고 있다. 실제로 이 아이디어는 2004년에 출판된 Refactoring to Patterns라는 책으로 실현되었다. 시간이 되는대로 Refactoring to Patterns를 읽어볼 예정이다.

Effective Java Programming Language Guide

Effective Java Programming Language GuideEffective Java Programming Language Guide, by Joshua Bloch

Effective Java Programming Language Guide (이하 Effective Java)는 Java 프로그래밍 언어를 잘 쓰기 위한 책에 속한다. 이 책은 Effective C++ 시리즈나 Exceptional C++ 시리즈처럼 하나의 조언과 그것에 대한 설명을 담은 57개의 항목들로 구성되어있다. 형식 뿐 만 아니라 내용을 보더라도 Java의 Effective C++과 같다고 봐도 무방할 것 같다.

Effective Java의 각 항목들은 반드시 Java 언어에만 국한되는 것이 아닌 일반적인 프로그래밍 원칙들 또는 객체 지향 프로그래밍에서 일반적으로 통용되는 프로그래밍 원칙들도 포함하고 있다. 그래서, Effective/Exceptional C++ 시리즈와 중복되는 항목들도 있다. (예를 들어, ‘Item 14: Favor composition over inheritance’ 와 같은 경우)

이런 종류의 책들은 한번만 읽는다고 해서 그 책들의 조언들을 완전하게 응용하기는 어렵다. 그래서, 단지 각 항목들의 리스트만이라도 주기적으로 보면서 조언들을 상기시켜주는 것이 좋다. (Effective Java의 항목 리스트) 특히, 거의 기계적으로 적용할 수 있는 항목들은 항상 기계의 도움을 받을 수 있도록 자동화해두는 것도 좋은 방법일 것이다. (지난 글에서 언급했던 FindBugs와 같은 이클립스 플러그인들이 도움을 줄 수 있을 것이다.) 한편, 각 항목들로부터 도출되는 보다 일반적인 프로그래밍 원칙들은 마음에 잘 새겨두는 수 밖에는 없을 것이다.

이 책이 출판된지 (2001년) 꽤 오래되었기 때문에, 현재 Java (특히 Java 5.0)의 상황을 반영하지 못하는 항목들이나 언급들이 약간씩 보인다. (예를 들어, type-safe enum 항목이나 doug lea의 concurrency 라이브러리에 대한 언급)  하지만, 반영하지 못하는 점들은 대체로 Java가 개선되었기 때문에 발생하는 것이어서 여전히 그 충고들 자체는 유효하다고도 볼 수 있다.

C++ 프로그래밍 언어에 관한 유명한 책들의 저자들이 해당 언어의 커뮤너티에서 상당히 유명하고 중요한 역할을 수행하고 있는 것을 보면, 분명히 이 책의 저자에 대해서도 알아두는 것이 도움이 될 것이다. Effective Java의 저자인 Joshua Bloch는 Sun Microsystems의 Distinguished Engineer 였고, Java 5.0 명세의 개발과정에도 중요한 역할을 했으며, 현재는 Google의 Chief Java Architect이다. 그는 이 책 이외에 Java Puzzlers도 썼는데, 국내에는 번역되지 않았기 때문에, 아마존에서 주문해서 읽어볼 예정이다.

Effective Java의 내용은 상당히 기본적인 내용에 해당하기 때문에, 실제로 Java 프로그래밍 언어를 사용하면서 깨닫게 되는 문제들을 고려하면 부족한 것이 사실이다. 최근에, 이 책과 같은 스타일의 또다른 책을 찾아보고 있는데, 아직은 없는 것 같다. Effective C++ 시리즈의 Scott Meyers나 Exceptional C++ 시리즈의 Herb Sutter와 같은 훌륭한 저자들이 Java 쪽에는 없는 것일까. Java 쪽의 유명인들이 부족한 것도 아닌데 말이다.

A Quote from "La Plaisanterie"

젊은이들이 연기를 하는 것은 그들의 잘못이 아니다. 삶은, 아직 미완인 그들을, 그들이 다 만들어진 사람으로 행동하길 요구하는 완성된 세상 속에 턱 세워놓는다. 그러니 그들은 허겁지겁 이런저런 형식과 모델들, 당시 유행하는 것, 자신들에게 맞는 것, 마음에 드는 것, 등을 자기 것으로 삼는다. ― 그리고 연기를 한다.

La Plaisanterie by Milan Kundera