좋은 품질이 되기까지 오랜 시간이 걸린다는 고정관념이 있다.
시작부터 저자의 말이다. 이전까지의 이야기를 몰라도 개발 경험이 있다면 좋은 품질이 대충 무엇인지 알 수가 있다.
나도 여러번의 비현실적인 일정 속에서 품질을 신경 쓸 수가 없었고, 좋은 품질이란 시간이 필요해야겠다는 관념이 있었는데 저자는 고정관념이라 표현한다.
안타깝게도 대부분 저급 품질의 싸고 빨리 만들 수 있는 코드를 선택하는 상황이 현실이다.
누구나 흔하게 접할 수 있는 상황이다. 이런 상황에 저자는 다음과 같이 말한다.
'고품질은 고비용'이라는 것이 편견임을 설명한다.
시간이 필요하지 않더라도 코드의 품질을 유지할 수 있다는 저자의 말이다.
품질은 선택사항이 아니다
비용이나 시장 타이밍 같은 트레이드 오프같은 문제만 없다면 누구든 품질이 높은 쪽을 원한다. 낮은 품질을 원하는 사람은 없다.
어떤 관리자나 고객도 나쁜 품질의 소프트웨어를 바라지 않는다.
심지어 개발자들이 일정과 비용을 맞추기 위해서 어쩔 수 없이 품질을 희생해야 한다고 말할 때도 고객을 끄덕이면서 속으로는 결과물의 품질이 좋기를 기대한다.
이 얼마나 모순되는 모습인가? 개발자들이 품질을 보장 못한다는 말에도 품질이 좋을 거라 기대한다니, 슬프게도 지금도 흔하게 접할 수 있다는 현실이다.
가장 근본적인 문제는 싸고 그저 그런 코드로도 충분하다는 매우 잘못된 가정을 할 때가 많다는 것이다.
누구라도 필요한 물건이 생겨서 사야된다면 값싸고 품질 좋은걸 원한다. 할 수 있는 것은 상품을 검색해서 가격과 평점으로 비교하여 구매하는 거다. 값싸고 품질이 높은 물건을 구매했다면 소비자는 만족해한다.
하지만 소프트웨어는 물건이 아니다. 변화에 맞게 변화하는 살아있는 생명체다.
관리자와 프로젝트 투자자는 개발자가 아니다. 그들에게 소프트웨어 개발은 그냥 돈을 내고 받는 서비스일 뿐이다.
그 어떤 경우에도 비용을 지불한 서비스의 결과물에 문제가 발생하는 일은 좋아하지 않는다.
너무나 맞는 이야기다. 나도 개발을 하지만 일상생활에서 흔하게 사용하는 소프트웨어를 돈을 주고받는 서비스로 생각한다.
할인을 받을 수 있으면 최대한 받아 값싼 돈을 주면서 원하는 기능이 없거나 문제가 생기면 언제든지 불만을 표한다.
좋은 품질은 비싸고 시간이 오래 걸릴까
장인이 개발 및 진행 중인 프로젝트라면 첫날부터 동작하는 소프트웨어가 고객에게 전달된다
?????!! 나는 전혀 이해가 되지않는다. 첫날부터 고객이 볼 수 있게 한 경험이 없고, 가능한지도 모르겠다.
기능 구현을 완료했다는 의미는 그 기능이 상용 시스템이나 비슷한 내부 검증 환경에 전개되었다는 의미다.
장인은 지속적인 통합과 초기부터의 제품 딜리버리를 목표로 하기 때문에 품질로 인해 상용 릴리즈가 지연되는 일은 가정에 없는 사항이다.
오만한 말로 들릴 수 있다. 하지만 그만큼 개발의 자부심이 남다른 의미로 느껴진다.
소프트웨어 장인이 작성한 코드는 테스트로 전체가 커버되기 때문에...
신규 기능들이 매뉴얼 테스트 단계 없이도 상용 환경에 지속적으로 전개될 수 있다.
애플리케이션이 커질 수록 효과가 크게 나타난다.
수작업으로 테스트하느라 시간을 낭비할 필요도 없고 버그를 고치느라 업무가 중단되지도 않는다.
장인이 작성한 테스트 코드에 대한 중요성을 이야기하고 있다. 시간이 지날수록 새로운 변화에 대해 낭비 없이 대응할 수 있다는 점은 엄청난 이점이다.
작은 코드 조각에서는 XP 실행 관례를 마스터한 소프트웨어 장인과 일반 개발자간의 업무 능력 차이가 별로 없을 수가 있다.
하지만 문제가 복잡해지면 차이가 어마어마하게 벌어진다.
테스트를 도입하지 않은 이전의 프로젝트 경험들과 교육이라도 통해서 겪어본 지금의 나는 그 차이가 이해된다.
시작 초기엔 별 차이가 없겠지만, 시간이 지나 프로젝트의 몸집이 커질 수록 그 격차는 비교할 수가 없게 된다.
장인을 더 많이 확보하여 팀 구성원들의 학습 곡선을 당기고 멘토링하는 데 관심을 기울여야 한다.
나도 저런 장인들이 있는 회사에 들어가고 싶다. 최소한 배움의 문화가 있는 회사로 가고 싶다.
테스트 주도 개발이 항상 필요할까
실용적인 대답은 '아니다'다.
도구나 실행 관례를 선택할 때는 실제로 처한 맥락을 반드시 고려해야 한다.
테스트가 주는 이점은 너무나도 좋다. 하지만 저자는 반드시 상황에 따라 고려해야 한다고 한다.
경험 많은 XP 개발자들은 모든 것을 테스트 기반으로 수행한다.
극히 드물지만 나도 TDD를 하지 않을 때가 있다. 그런 경우는 자동화된 테스트가 별 의미가 없는 상황으로, 대부분 사용자 인터페이스의 동작 방식에 관련된 것들이다.
상황에 따라 알맞게 대응해야겠다.
리팩토링
리팩토링을 위한 리팩토링은 시간낭비다.
꾸준하게 코드를 리팩토링하는 것은 좋은 일인데 왜 시간낭비라 할까?
특별한 이유도 없이 코드를 열어서 재정리하는 일은 아무런 의미가 없다.
실용적인 관점에서는 그저 시간 낭비일 뿐이다.
실용적인 관점에서 시간 낭비일뿐이라니? 리팩토링의 중요성을 말했던 이전과는 다른 모습에 당황스럽다.
새로운 기능을 추가할 때 마다... 필요한 경우 리팩토링을 하여 레거시 코드가 새로운 기능을 자연스럽게 받아들일 수 있도록 해야 한다.
새롭게 추가할 기능이 코드에 큰 영향을 준다면 사전에 영향이 가해지는 부분을 리팩토링하는 것이 바람직하다.
아~! 새롭게 기능이 기존 레거시 코드에 영향이 가면 그 부분을 리팩토링하는 뜻이였다.
중간에 생략한 내용이 있는데 지금 언급해야겠다.
보이스카웃 원칙에서는 '처음 발견했던 것보다 더 깨끗하게' 캠프를 남겨 둘 것을 이야기하고 있지 '캠프 전체를 혀로 핥아도 될 정도로 반짝반짝하게 만들라'는 뜻은 아니다.
전체적인 리팩토링을 하는게 아니고 필요한 부분만 리팩토링하라는 이야기다.
새로운 기능을 받아들이기 쉬운 상태로 만들어야 한다. 받아들이기 쉽다는 것의 의미는
새로운 기능으로 인한 영향을 최소화한다는 것을 의미한다. 즉 '확장에는 열려있고 변경에는 닫힌' OCP 원칙을 준수할 수 있도록 코드를 리팩토링한 후에 신규 기능을 추가한다.
데이터 중심의 절차지향적인 개발을 해왔던 나는 다시 되돌아간다면 OCP 원칙을 적용할 부분이 너무 많다고 생각된다.
지금까지 배운 내용으로 그 시절로 되돌아간다면 리팩토링할게 너무나도 많다. 다행히도 그만큼 내가 변했다는 의미다.
비즈니스 돕기
진정으로 원하는 바가 무엇인지 비즈니스 담당자 스스로도 잘 모르는 프로젝트들을 흔하게 볼 수 있다.
진짜 흔하게 볼 수 있다. 너무나도 흔해서 문제다. 고객이 요구사항을 모른다. 고객이 넘긴 요구사항에 대해서도 고객 내부에서 잘못되었다고 서로 싸우는 광경까지 본적이 있다. 매일 요구사항이 변경되고 설계도 바뀐다 데이터베이스 테이블 구조도 실시간으로 변경된다. 프로젝트가 이상하게 흘러간다. (처음에 고객이 기획서까지 완성된 상태라 말했었다.)
애자일 코치들은 개발자들이 비즈니스 담당들과 직접 대화하면서 질문하고 솔루션을 제안할 것을 권장한다. 같은 팀이 되어 도와야한다.
단순 갑과 을의 관계가 아니라 생산적인 동반자로 접근하여 도와야한다는 말이다.
하지만 동반자가 되려면 전제 조건이 있다. 비즈니스 담당자도 개발자를 단순하게 공장 노동자로 취급하지 않아야한다.
비즈니스 부서는 아직도 자기들이 뭘 원하는지 파악중이었고 제시할 수 있는 것들은 계속 바뀌는 설익은 것들뿐이었다.
가장 좋은 방법은 뭐든 최대한 빨리 만들어서 이들앞에 내놓은 것이었다.
실시간으로 변화하는 요구사항이라도 빠르게 대응하여 보여주는 것만으로 고객에겐 요구사항을 정하는게 큰 도움이 될 수 있다.
나는 이런 비슷한 경험을 겪은 적이 여러번 있다. 한번은 예전 첫회사에서 프로젝트를 진행했을 때랑 나중에 플랫폼을 서비스하면서의 상황이다.
우선 위에서 언급했던 비슷한 경험은 고객 내부에서 매일 정치하며 싸우는 상황이라 역효과만 난적이 많았다. 화면을 보여주면 오히려 상대편을 헐뜯는 상황이 많이 발생했다. 프로젝트는 점점 늪에 빠져 헤어날 수가 없는 상태가 되었다.
다른 경험은 정확한 정책도 설립이 안된 상태에서 큰 틀을 중심으로 구현하여 보여준 경험이다. 저자의 경험처럼 고객에게 구현된 결과물을 보여주는 것은 고객에게 하나씩 요구사항을 정리할 수 있게 큰 도움이 된다.
생략하고 넘어가겠다.
여기서의 요점은 개발팀 차원에서 비즈니스를 도울 방법을 찾아서 실행했다는 점에 주목해야한다.
개발자는 단순히 위에서 시키는 대로만 움직이는 존재가 아니다. 고객에게 제안을 하거나 결과물을 보여주면서 좀 더 좋은 방향으로 생산적인 동반자로 나아가야 한다.
소프트웨어 프로젝트는 우리를 위한 것이 아니다
프로페셔널로서, 소프트웨어 프로젝트가 개발자를 위한 것이 아니라는 사실을 이해할 필요가 있다.
프로젝트는 고객의 이익을 위한 것일까? 무슨 말을 한건지 궁금하다.
프로젝트를 수행한 사람들이 떠나간 후 그것을 유지보수할 사람들을 고려해야만 한다. 원저작자들 없이 소프트웨어를 진화시켜야 하는 회사의 어려움을 이해해야 한다.
훗날 회사를 떠나게 된다면 누군가에게 나의 업무와 코드를 설명해줘야 한다. 만약 알려줄 수 있는 개발자도 없다면 문서라도 남겨야한다. 이후 새로운 개발자가 들어오게 되면 그 사람은 나의 업무와 코드를 잘 이해하고 계속 이어나갈 수 있을까? 파악하는데 어렵지 않을까 생각해본다.
비범함과 평범함
그 어떤 바보같은 개발자도 뭔가를 동작하게 만들 수는 있다. 비범한 개발자와 평범한 개발자를 가르는 기준은 어떤 방식으로 그것을 동작하게 만드느냐이다.
저자의 말대로 누구나 개발은 할 수 있다. 다만 어떤 방식으로 동작하는 지가 중요하다.
비범한 개발자는 가장 단순한 코드를 만들어 경험이 적은 개발자가 이해하는 데 아무런 문제가 없도록 한다.
여기서 비범함과 평범함의 차이가 나온다. 비범한 개발자는 요구사항만을 위한 코드가 아니라 다른 개발자가 봐도 쉽게 이해할 수 있도록 작성한다. 이전에 언급된 원저작자들이 없이 소프트웨어를 진화할 수 있도록 신경을 쓴다.
비범한 개발자들은 심지어 코드 한줄도 짜지 않고 문제를 해결할 방법을 찾는다. 가장 훌륭한 코드는 작성할 필요가 없는 코드다.
작성할 필요가 없는 코드라니... 상상조차도 안된다. 이런 경우를 들어보지도 않아서 궁금하다.
단순한 설계를 위한 네 가지 원칙
다음은 켄트 벡이 말한 네가지 원칙이다.
1. 모든 테스트를 통과해야 한다
2. 명료하고, 충분히 표현되고, 일관되어야 한다.
3. 동작이나 설정에 중복이 있어서는 안된다.
4. 메서드, 크래스, 모듈의 수는 가능한 적어야 한다.
저자는 위의 네가지 원칙을 다른 버전으로 언급한다.
나는 J.B 레인스 버거의 버전을 선호한다.
1. 모든 테스트의 통과
2. 중복의 최소화
3. 명료성의 최대화
4. 구성요소의 최소화
나는 중복 제거보다는 명료함을 항상 우선시한다. 단순한 설계를 위한 가이드 라인으로 좋은 네이밍과 비즈니스 콘셉트를 잘 투영한 추상화에 집중한다.
최근 교육을 통해 네이밍의 중요성을 깨달았다. 이전까지 네이밍에 신경은 안쓴게 아니였지만 (용어사전으로 정해진 네이밍을 따름) 다른 사람이 이해할 수 있도록 비즈니스를 녹인 네이밍 정하기는 많은 노력이 필요할 거 같다.
중복을 제거하면서 코드의 응집성과 독립성을 높인다. 중복을 제거하다 보면 새로운 구조가 떠오르고 다시 명료성을 높인다...
이 접근 방법이 도메인 기반 설계, SOLID 원칙과 결합되면 꽤 괜찮은 코드를 만들어 낼 수 있다. 불필요한 여러 가지 설계적, 아키텍처적 패턴들로 코드가 오염되는 것을 막아준다.
이 내용은 쉽게 얻을 수 있는 경험과 기술이 아니고 꾸준히 노력하고 쌓아서 얻게되는 결과물이라 보여진다.
장인정신과 실용주의
실용주의가 없는 장인정신은 장인정신이 아니다. 장인이 가장 중요하게 초첨을 맞추는 것은 고객의 만족이다.
고객이 소프트웨어 프로젝트를 통해 무엇을 성취하려 하는지 반드시 이해해야 한다.
단순히 요구사항만 충족시키는게 아닌 동반자의 역할로서 고객이 무엇을 하려는지 비즈니스를 이해해야한다.
서로 다른 프로젝트는 각각 다른 접근 방법이 필요하다.
프로젝트마다 같은 맥락과 상황이 생기는게 아니다. 다른 맥락과 상황인 프로젝트를 접하게 될테고 그에 맞는 대응을 해야한다.
프로젝트이 크기나 복잡도가 어떻든 간에, 소프트웨어 장인은 항상 높은 품질의 코드를 생산해낸다.
깨끗하고 잘 작성된 코드는 비즈니스의 요구에 맞추어 빠르고 안전한게 변경할 수 있는 기반이 된다.
장인은 어떤 상황에서든 높은 품질의 코드로 이끈다고 말한다.
후기
나는 이번 챕터를 통해 장인처럼 실용주의적으로 모든 상황을 접근했는지 되새기고 반성하는 시간이 되었다.
비록 바뀔 수 없는 잘못된 환경에서의 경험이 포함되지만 시도라도 안했다는거에 반성해본다.
주요 주제는 단순하게 실용주의였지만, 다양한 내용을 품고 있다.
언젠가는 내가 프로젝트를 떠나도 소프트웨어 진화를 책임질 다음의 개발자를 위한 내용과
리팩토링을 언제 해야하는지에 대한 선택과정까지
앞으로 개발자로 살아가는데 도움이되는 값진 내용이 많았다.
'서적 > 소프트웨어 장인' 카테고리의 다른 글
[CHAPTER 16] 소프트웨어 장인으로서의 커리어 (마지막 챕터) (0) | 2021.05.17 |
---|---|
[CHAPTER 14] 기술적 변화의 실행 (0) | 2021.05.13 |
[CHAPTER 13] 배움의 문화 (0) | 2021.05.12 |
[CHAPTER 12] 낮은 사기의 대가 (0) | 2021.05.12 |
[CHAPTER 11] 잘못된 면접 방식 (0) | 2021.05.10 |