본문 바로가기

리뷰/책 리뷰

[IT/리뷰] 애자일 프랙티스

728x90

애자일 프랙티스 : 네이버 도서 (naver.com)

 

애자일 프랙티스 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

요즘 애자일에 대한 경험을 더 갈구하고 있다. 그러다 보니 책으로라도 계속해서 준비할겸 배우고 싶은 마음이 크다.

 

이 책은 평소에 다른 애자일 관련 책을 읽다가 추천을 받은 책이다. 개인적으로 그다지 재밌다고 느껴지지는 않았다. 다른 애자일 관련 책이랑 비교해서 재미가 있지는 않았다. 그런데 추천해주셨던 분은 재밌다고 하셨기 때문에 개인적인 차이인 것 같다. 아마 그분도 애자일을 직접적으로 경험해보지 못하셨다보니 책으로 접하셨을텐데 나와 읽은 책의 순서가 다른 것이 아닐까 싶다.

 

그렇다고 이 책이 애자일을 아예 모르는 사람이 읽기에 좋은 책도 아닌 것 같기는 하다. 개념서 느낌은 아니고 실제 개발 환경에서 적용해야하는 것들이 무엇인지 전달하는 책이기 때문이다. 애자일을 처음 접하는 사람이 읽기에는 내용도 많고 단순히 '이건 나한테는 지금 불가능해'라며 생각하고 넘어갈 뿐 마음에 와닿지는 않을 것 같다. 책의 이름처럼 상황별로 애자일을 적용하는 방식들을 나열한 것일 뿐이라 느껴졌다.

애자일을 처음 접하는 사람에게는 별로일지 몰라도 애자일을 어느정도 알거나 도입하고 있는 곳에서는 도움이 될 것 같다. 현재 부족한 부분은 무엇인지, 어려움을 겪고 있던 부분은 무엇인지 등을 점검할 수 있을 것 같다.

 

지금 다니는 회사는 자체 솔루션이 있는 회사라 폭포수 모델과 같이 프로젝트가 진행된다. 변경할 수 있는 작은 부분들이라도 애자일로의 전환이 있으면 좋겠다. 최근에 TDD를 공부하고 있는 것도 나라도 작은 시도를 하기 위해서다. 애자일의 장점들이 많이 있으니 회사도 긍정적으로 프로세스를 검토해 좋지 않은 부분은 변경하면 좋겠다.

 

책 전반적으로 다른 애자일 책에서도 다루는 내용들이 많다. 그중에서 다시 봐도 인상 깊었던 부분이나 괜찮았던 내용들을 아래에 정리해보았다.


이 책의 저자인 앤디 헌트를 포함한 17명이 2001년에 떠오르던 경향인 경량 프로세스에 대해 토론을 시작했다. 여기에는 읽었던 다른 책들의 저자이자 유명한 개발자인 로버트 C. 마틴, 켄트 벡, 마틴 파울러, 제임스 W. 그레닝, 커닝험 등도 포함된다. 이들은 장황하고, 부산물 많고, 결과는 부실한 프로세스 때문에 실패하는 프로젝트를 많이 보아온 사람들이었다. 그렇게 '애자일'이라는 새로운 용어를 만들며 더 중요한 것에 집중하는 방식을 정립해 공표했다.

'애자일'은 사람(people), 협조(collaboration), 반응성(responsiveness), 동작하는 소프트웨어(working software)를 강조한다. 이 접근 방법은 빠르게 반응해 상호 협력하는 사람들과 논증 가능한 구체적인 목표(실제 동작하는 소프트웨어)를 결합하는 것이다. 그러니 계획에 기반해 개별적으로 분리된 에피소드로 발생하는 중요한 사건들이 끊임없이 지속 가능하게 처리된다.

팀에 속하는 모든 사람들은 프로젝트에서 긍정적인 성과를 원하는 전문가라 가정한다. 비록 경험이 풍부한 전문가가 아닐 수 있어도 전문가다운 자세를 지닌다. 즉, 모든 사람이 최선을 다하기를 원한다는 것이다.

 

프로세스 준수는 결과가 아니다. 다들 프로세스에 따라 정확히 작업했다는 사실을 측정하고 평가하고자 한다. 하지만 프로세스를 잘 따르는지 재는 것은 결과를 측정하는 것이 아니다. 애자일 팀은 프로세스보다 결과에 가치를 둔다.

 

설계가 코드를 강요하는 것이 아닌 코드를 안내하도록 하라. 당장 필요한 설계를 미리 할 대조차 예기치 못한 일들이 생긴다. 현재 시점에 따라가는 설계는 요구사항에 대한 현재의 이해가 기초한 것임을 알아야 한다. 설계와 설계를 구현하는 코드는 끊임없이 진화한다.

 

설계에는 두 가지 수준이 존재한다. 전략적(strategic)인 설계전술적(tactical)인 설계다. 선행 설계는 전략적인 설계로, 대개 아직 요구사항에 대한 이해가 깊지 않을 때 이뤄진다. 이런 설계는 일반적 전략을 표현할 뿐 정확한 세부 내용을 파고들지 못한다. 예를 들어 메서드, 매개변수, 필드 등의 세부 내용이나 객체 간 상호작용의 순서에 대한 세부 내용을 명시해서는 안 된다. 좋은 전략적 설계는 올바른 방향을 가리키는 지도와 같은 역할이다.

전술적 설계는 프로젝트가 진화할 때에만 드러난다. 하지만 개별적 메서드나 데이터 타입에 집중한 전술적 설계보다는 책임의 관점에서 가능한 클래스 설계를 논의하는 것이 더 적절하다. 책임 관점에서의 클래스 설계는 여전히 고수준의 목표 지향적 접근 방법이기 때문이다.

클래스는 다음과 같은 용어로 설명된다.

  • 클래스 이름(Class name)
  • 책임(Responsibilities) : 클래스는 무슨 일을 해야 하는가
  • 협력자(Collaborators) : 작업을 완료하기 위해서 어떤 다른 객체와 같이 작업하는가

좋은 설계는 무엇일까? 설계의 성격상 가장 좋은 피드백은 코드에서 온다. 요구사항이 조금 변해도 계속 구현하기 쉽다면 그 설계는 좋은 설계라 할 수 있다. 요구사항이 조금 변했을 때 큰 혼란이 온다면 설계를 개선해야 한다.

좋은 설계는 정확(accurate)하지만 정말(precise)한 것은 아니다. 설계에서 말하는 내용은 맞아야 하지만 변하거나 불확실한 세부 내용을 포함해서는 안 된다. 설계는 의도인 것이지 조리법이 아니다.

 

설계를 할 때 '미리 대규모로 설계할 수 없다'는 말은 설계가 진짜로 없다는 것이 아니다. 단지 실제 코드로 검증하는 일 없이 설계를 하지 말라는 것이다. 설계에 대한 고민 없이 코딩을 하는 것은 위험하다. 괜찮은 경우는 배우거나 프로토타입을 만들 때뿐이다.

초기 설계가 쓸모없는 것으로 결론이 나더라도 설계는 필요하다. 미국 대통령이었던 아이젠하워는 '계획이라는 말만으로는 가치가 없다. 계획을 실행하는 일이 필수적이다.'라고 말했듯이 설계 자체가 아니더라도 설계 도중에 배우는 일은 가치가 있다.

 

소프트웨어 개발의 성공은 고객의 기대에 얼마만큼 가깝게 마무리 짓느냐에 달렸다. 이는 고객의 입력과 피드백을 자주 받을 때 개발의 결과가 고객의 기대와 최대한 일치하게 된다. 고객과 이야기를 자주 한다면 모두에게 이득이다. 고객은 진행 상황을 더 잘 알게 되고 고객 스스로 요구사항을 정리할 수 있다. 진행 상황과 사용 가능한 시간, 예산의 맥락에서 고객은 일의 우선순위를 정할 수도 있다. 개발자는 고객의 실제 필요에 가깝게 프로그래밍할 수 있다.

 

그렇다고 매일, 매주 또는 격주 회의는 너무 잦아 어떤 고객은 감당할 수 없을 수 있다. 그런 고객은 이미 자기 일이 꽉 차 있는 것으로 고객의 시간을 존중해야 한다. 고객이 매달 회의가 편하다면 매달 회의를 해야 한다.

어떤 고객의 직원은 데모를 시연하는 회의에 참여하는 것이 일인 경우도 있다. 그 사람은 시간마다 피드백과 데모를 보여주지 않으면 만족하지 않는다. 피드백에 대한 효과야 좋겠지만, 개발자는 너무 일이 많아서 감당할 수 없다는 사실을 알면서도 보여주기 위한 코딩을 계속하게 된다. 이때는 일정을 재조정해 정말 완료했고 뭔가 보여줄 내용이 있을 때 만나서 데모를 시연해야 한다.

데모의 목적은 고객이 피드백을 주고 프로젝트를 조정하는 데 있다. 기능이나 안정성 부족으로 고객을 화나게 해서는 안 된다. 안정성이 없다면 보여주지 말아야 한다. 결국 고객이 보고 있는 애플리케이션은 개발 중이며 최종 완성품이 아니라는 것을 알려야 한다.

 

소프트웨어 프로젝트는 변덕스럽고 재생 불가능한 성격이 있다. 따라서 고정 가격을 들고 나오는 것은 깨질 수밖에 없는 약속이다. 견적을 더 잘하든가 다른 종류의 거래를 협의해야 할까?

미리 절대적인 가격을 제시해야 한다면 COCOMO나 기능점수 분석과 같이 꽉 짜인(heavy-duty) 견적 기술로 조사해야 한다.

하지만 대부분의 프로젝트는 그렇지 않다. 고객에 따라 크게 변할 수 있는 경우도 있다. 발견과 발명이 필요한 프로젝트는 협력해서 다루어야 한다. 다른 방법도 있겠지만 애자일에서는 다음과 같은 단계로 진행되는 경우도 있다.

  1. 초기에 작고 유용한 시스템 일부를 만드는 것을 제안하라. 충분히 작은 기능만 골라서 6주 내지 8주 이상 걸리지 않도록 하라. 모든 기능은 아니더라도 충분한 기능 구현을 통해 사용자의 실제 생산성 향상을 도와라.
  2. 첫 반복 주기 마지막에 고객은 두 가지 선택 사항을 갖는다. 다음 기능을 제공하는 반복을 계속하는 것에 동의하는 것과 계약을 취소하고 수 주간 작업한 내용에 대해서만 비용을 지불하는 것이다.
  3. 고객이 계속 진행을 원할 경우, 다음 반복 동안 무엇을 할 수 있을지 예상하기에 더 좋은 상황이다. 다음 반복에서도 고객은 여전히 두 가지 선택 사항을 갖는다.

결국, 고객 입장에서 프로젝트가 어두워 보이지 않게 되는 것이 필요하다. 고객은 일찍부터 진행 내용을 확인하며 프로젝트를 제어하거나 그만둘 수 다. 고객은 전체적으로 위험을 덜 겪으며, 개발자는 반복적이고 점진적 개발을 수행하게 된다.

 

단, 첫 번째 반복이 끝나고 반드시 견적을 제시해야 한다. 그렇지 않다면 허황된 약속이라도 견적을 주는 누군가에 계약을 뺏길 것이다.

애자일이 단순히 '일단 코딩을 시작하고 끝난 다음에야 결과를 알 수 있다'는 것이 아니다. 현재 지식과 가정 아래에서 어떻게 그런 견적을 냈는지, 오차 폭은 어느 정도인지 설명과 함께 견적을 낼 필요는 여전히 있다.

반드시 고정 가격으로만 일을 해야만 한다면 정말로 훌륭한 견적 기술이 필요하다.

일의 주문 내용(Statement Of Work)의 진행에 따라 정해질 반복의 회수를 정하지 않고, 반복 주기마다 가격을 고정하는 계약을 고려할 수도 있을 것이다.

 

더 많은 클래스가 더 좋은 디자인이 아니다. 객체지향으로 개발을 할 때 더 많은 객체의 클래스를 만들도록 강요되는 경우가 있다. 클래스가 필요 없는 경우에 쓸데없이 코드를 추가하는 것은 옳지 못하다.

TDD를 사용하면 코드를 작성하기 전에 코드를 어떻게 사용할지를 먼저 고민하게 된다. 사용성, 편리성에 대해 고민을 하게 되면 더 실용적인 설계에 도달할 수 있다.

의도를 갖는 것이 더 많은 클래스나 타입을 의미하는 것이 아니다. 의도는 과도한 추상화에 대한 변명이 되지 못한다.

 

개발을 할 때는 편리함보다 읽기 쉬움을 선택해야 한다. 코드는 작성되는 것보다 읽히는 것이 더 많다. (일부 예외 상황은 있겠지만) 성능이 좋지 않더라도 읽기 쉽다면 더 가치 있는 코드다.

새로운 기능을 추가하거나 버그를 수정하려 한다고 해보자. 가장 먼저 코드가 어떤 일을 하고 어떻게 동작하는지 이해해야 한다. 이 첫 번째 단계인 코드 이해가 가장 어려울 것이다. 단순 상수보다는 enum과 같은 개념을, 시프트 연산보다는 곱셈 연산자를 등 읽기 쉬운 코드를 작성하자.

 

상황에 일치하는 결합(coupling)을 사용해야 한다. 해시 테이블을 통해 느슨한 결합을 하는 것은 실제 생활에서 컴포넌트가 느슨하게 결합된 상황을 의도한다. 밀접하게 결합된 컴포넌트는 해시 테이블이 아닌 명확한 의도를 표현하는 방법을 사용하자.

 

프로그래머는 일반적으로 문서 작성을 싫어한다. 최신으로 유지하기 어렵고 DRY(Don't Repeat Yourself) 원칙을 어길 수도 있다. 이런 경우는 문서가 없는 것보다 나쁘다. 그럼에도 코드를 문서화할 필요가 있다.

코드 자체로 표현할 수 없는 부분은 주석이 필요하다. 예를 들어 메서드가 하는 일을 이해하기 위해 메서드 전체를 읽을 필요 없이 주석 한 줄로 메서드의 동작을 설명하는 것이다. 단순한 주석을 통해 메서드의 목적과 의도한 결과, 조심해야 할 점까지 빠르게 알 수 있다.

 

그러나 작성하는 대부분의 코드나 메서드의 본문 안에는 주석이 필요하지는 않다. 주석이 아니라 소스코드의 정밀함과 명료함 때문에 소스코드를 이해하기 쉬워야 한다. 변수명과 화이트 스페이스를 적절히 사용하고, 로직을 세심하게 분리해 간결하게 표현하는 게 필요하다.

 

코드의 단순함은 극단적일 정도의 단순함이 아니다. 아마추어 같고 불충분함이 아니다. 오히려 복잡하고 뒤얽힌 해결책보다 얻기 어려운 것이다. 여기서의 단순함이란 많은 양의 묽은 죽이 아니라 진하고 훌륭한 소스와 같은 것이다. 패턴, 원칙, 기술을 사용해야 하는 부득이한 사정이 있을 때만 이들을 포함시키자.

728x90