애자일 소프트웨어 개발 중에서 처음 제안이 되기도 했고, 가장 극단적인 방법이 Extreme Programming(XP)이라고 볼 수 있다. 프로세스 적인면에서 특히 그렇다. 또한 짝 프로그래밍(Pair programming), 지속적인 통합(Contiunous Integration), 테스트 주도 개발(Test-drinven development)와 같은 많은 실천법이 다른 개발에서도 채용되기도 했다.

 

여기서는 마틴 파울러의 2004년도 글[1]을 요약한 것이다. 원문을 읽어 보면 알게되지만, 마틴 파울러는 켄트 벡과 같은 좀 더 극단적인 XP 추종자들 보다는 더 실용적고 다른 접근 방법에 대해서도 열려 있는 것으로 보인다. 이 부분은 아키텍처 설계에 대한 관점에서 부터 크게 차이가 난다.

 

계획 설계(Planned Design)과 진화적 설계(Evolutionary Design)

마틴은 프로젝트 초반에 충분한 시간을 들여 소프트웨어 설계하고 진행하는 기존의 방식을 계획 설계라고 하고 XP와 같이 설계하는 단계 없이 점진적인 개발에서 나오는 소프트웨어도 아키텍처 혹은 구조가 있다고 하고 이를 진화적 설계로 불렀다.

   

애자일 개발에서 진화적 설계에 대해서 일반적인 비판은 임시 방편의 모음이라는 것이다. 마틴은 글에서 "우선 코딩하고 문제는 나중에 고친다(code and fix)"라고 설명하고 있다. 그리고, 시간이 지남에 따라 점점 더 코드에 기능을 추가하기 힘들어 지고 버그 수정 비용도 기하급수적으로 증가한다고 지적한다.

 

그렇다면, 반대로 계획 설계에는 문제가 없는가? 계획 설계에서는 설계자와 구현 담당자가 분리된 경우 종종 있다. 이러한 환경은 구현을 하는 동안에 해결해야 하는 문제를 설계자가 생각할 수 없어 문제를 만들기도 한다. 또한, 많은 개발자가 경험하지만, 요구 사항은 지속적으로 변하게 되어 있다. 이러한 문제들도 계획된 디자인을 유연하게 만들지 못하고 결국에는 "우선 코딩하고 문제는 나중에 고친다"의 접근법을 사용하게 된다고 마틴은 주장한다.

XP에서의 진화적 설계가 가능하게 하는 실천법

마틴은 이러한 문제의 해결법이 바로 XP에서 사용하는 실천법이라고 한다. 즉, 지속적인 테스팅(TDD)과 지속적인 통합(Continous Integration)이다. XP에서는 구현하기 전에 요구 사항을 테스트하는 테스트 코드를 만들고 이를 구현하고, 구현된 테스트 케이스들이 기존 코드의 동작을 보장하는 테스트 주도 개발(Test Driven Development)를 사용한다. 이를 통해서 다른 팀이 개발하는 기능의 통합도 매시간 혹은 매일하게 된다 (Continous Integration).

 

그 유명한 리팩토링[2]을 쓴 마틴은 리팩토링의 효과도 강조한다. 주먹구구의 느슨한 구조의 재구성과 비교해 XP에서 이야기하는 리팩토링은 아주 강력한 효과를 제공한다고 이야기 하고, 마틴으 켄트 벡으로 부터 이를 배우고 난 후에 자신이 책까지 썼다고 이야기 한다. XP에서 이야기하는 리팩터링은 TDD를 위한 테스트 코드가 존재해야 하고, 기능을 추가하지 않은 상태에서 구조를 변경하는 것이다. 리펙터링의 단순한 예제들을 따라해 봐도 이러한 것이 주는 효과는 분명하다.

 

디자인 패턴에 대한 마틴의 의견은?

나도 애자일 선언문[3]의 12가지 원칙 중 가장 좋아하는 부분이 "단순성이 -- 안 하는 일의 양을 최대화하는 기술이 -- 필수적이다(Simplicity--the art of maximizing the amount of work not done--is essential)"이다. 마틴도 이 단순성을 매우 강조한다. 즉, 현재 단계에서 필요한 것만 구현하는 것이다.

 

디자민 패턴에 대해서도 마틴은 다음과 같은 조언을 한다. XP 추종자들에게 하는 조언이기는 하지만, 애자일리스트에게는 누구에게나 적용될 수 있다.

  • 패턴에 대해 학습하는 시간을 미리 해두자.
  • 패턴을 언제 적용할 것인지 시기에 집중한다. 너무 일찍 적용하지 않도록 하자.
  • 먼저 가장 단순한 형태로 패턴을 구현하는 방법에 집중하고 복잡한 것은 나중에 추가하자.
  • 패턴을 넣었지만 충분한 효과가 없다고 생각되면 과감히 제거하라.

 

아키텍처 키우기

이 글[1]에서 마틴 파울러의 유명한 소프트웨어 아키텍처에 대한 정의가 나오기도 한다. 그는 소프트웨어 아키텍처를 시스템의 변경하기 어려운 부분인 시스템의 핵심 요소(core element)의 개념(notion)이라고 정의 한다.

 

물론 마틴은 자신을 켄트 벡과 같은 극단적인 XP 추종자가 아니라고 인정하면서 초기 소프트웨어 아키텍처가 필요하다고 이야기 한다. 하지만, 이 설계가 확정되어서 바뀌지 않는다고 생각하지 않는다. 도리어 초기 결정에 문제가 있을 수 있다는 것을 인정하고 과감하게 변경할 수 있어야 한다고 이야기 한다.

 

예를 들어 Enterprise Java Bean(EJB)와 같은 개발 언어는 초기에 결정해야 하는 중요한 결정일 수 있다. 그렇다면 EJB를 쓸지 않을지 결정은 프로젝트의 초기에 하는 것이 좋을까 가능한 늦게 하는 것이 좋을까? 당연히 가능한 초기에 결정하는 것이 좋을 것이다. 그렇다면, 과제를 시작하면서 바로 결정하는 것이 가장 좋을 것이다. 다시 생각해 보자. 그렇다면, 우리 과제에 EJB가 필요한지 아닌지 어떻게 알 수 있을까? 이를 확인하기 위한 진행이 가장 먼저 선행되어야 할 수 있다. 그 결과 EJB를 프로젝트에서 쓸지 아니면 쓰지 않을지 아키텍처적으로 결정하고 진행할 수 있을 것이다. 이 것이 마틴이 주장하는 소프트웨어 아키텍처를 진화적으로 활용하는 요체라고 할 수 있다.

 

전통적인 XP 추종자들은 아마도 데이터베이스가 필요할 때까지 데이터베이스를 적용하는 것을 가능한 미룰 것이다. 하지만, 마틴은 많은 사용자가 사용하는 시스템에서 다량의 데이터가 있다면 첫날 부터 데이터 베이스를 고려하고, 복잡한 비지니스 로직이 보이면 도메인 모델을 아키텍처에 넣으라고 조언한다.

 

문서화(UML 사용하기)

문서는 애자일리스트에게서는 적과 같다. 그렇기 때문에 UML에 사용도 그렇게 치부되어 왔다. 하지만, 많은 애자일을 따르는 개발자들이 단순화 된 UML을 사용하는데 이 또한 마틴에게 영향 받은 것을 보인다.

 

마틴은 다이어그램을 잘 사용하기 위한 조언도 제공한다.

  1. 다이어그램의 일차적 가치는 소통이므로 이를 읽을 독자를 먼저 두어야 한다. 즉, 중요한 것은 넣고 덜 중요한 것은 빼는 것이 중요하다고 강조한다.
  2. 어려운 작업일 수록 모여서 빠르게 설계 세션을 가지는 것이 중요하다고 이야기 한다. 하지만, 이 세션은 짧고, 중요한 사항만 다르며, 결과물은 최종 디자인이 아닌 스케치로 간주한다.
  3. 이러한 선행 설계는 잘못된 부분이 반드시 있을 수 있다는 것을 인정하고, 구현하면서 발경하면 디자인을 변경해야 한다는 것이다. 
  4. 디자인을 변경한다고 해서 다이어그램을 변경할 필요가 없다. 디자인을 이해하는데 도움이 되었다면 충분하고 그 다이어그램은 버려도 된다.
  5. 다이어그램이 지식 전달(Knowledge Transfer)할 때에도 유용고 중요한 문제를 요약하고 강조하는 역할을 한다. 하지만, 코드가 가장 자세한 정보의 저장소임을 잊지 말자.

경력이 쌓이면 아키텍트가 되길 원하나요?

결론 부터 이야기 하면, 마틴은 테크니컬 리드가 되라고 이야기 한다. 아키텍트라고 하면 개발 업무에서 멀어지고 코딩을 하지 않는 높은 사람처럼 보인다. XP에서 하듯이 경험많은 개발자는 자신의 기술을 강화하고 팀의 여기 저기를 다니며 코칭과 가르침을 주는 것이 더 의미있다고 주장한다.

 

여기서 고민을 해보자. 이글은 2004년도의 글이다. 2022년 내가 알고 있는 테크니컬 리드의 상반되는 양쪽 극단은 어떤 것일까? 아마도 자신의 도메인에서 경험이 아주 많은 아키텍트가 있을 것이고, 다른 한쪽에는 실무 능력을 아주 무섭게 키운 소프트웨어 장인(Software Craft)가 있을 수 있겠다. 이 두 사람 모두 자신과 연결된 사람들에게 긍정적인 영향을 끼치며 프로젝트가 좋은 방향으로 흘러가게 기여하고 있다고 가정해 보자.

 

아키텍트는 코딩이나 심지어 코드리뷰도 전혀 하지 않을 것이다. 그가 하는 일은 도메인의 지식을 넓히기 위해 트렌드를 익히고, 매일 다이어그램을 그리고 이를 기반으로 몇몇의 모듈 개발 팀의 일부 인력들(리더 혹은 그 팀의 아키텍트일 수 있고 개발자 일 수도 있다)과 소통하며 방향을 잡을 것이다. 또한, 이 인력들에게 아키텍처 설계에 대해 코칭하고 가르치고 있을 것이다. 소프트웨어 장인은 늘 자신의 개발 역량을 강화하기 위해 반복 연습(카타, 태권도의 품새 같은 연습 루틴)을 하고 새로운 기술을 익힐 것이다. 자신의 담당 모듈의 완성도를 높이며, 자신이 속해 있는 동료들과 협력하며 그들을 코칭할 수 있는 것을 생각해 볼 수 있다. 

 

이 둘은 서로 다르지만, 또한 비슷한다. 자신의 역량을 강화하고, 프로젝트를 위해 기여를 하며, 주변에 있는 동료들을 코칭하며 가르칠 것이다. 우리는 이 두 사람 사이에 어디엔가 있을 것이다. 그렇다면, 올바른 길을 가고 있는 것이라고 이야기 하고 싶다.

 

가역성(Reversibility)

마틴은 글에서 애자일 방법론에서 가역성의 중요합에 대해서 이야기 한다. 이 부분이 아키텍처에서도 중요하다는 것이다. 즉, 진화적 설계의 측면에서 되돌리기 쉬운 것은 덜 중요한 것이고 되돌릴 수 없는 결정이 중요한 결정이라는 것이다. 이러한 평가를 위해서 미래의 변경이 얼마나 어려울지 실험해 보는 것도 의미가 있다고 이야기 한다.

 

진화적 설계가 일어나고 있는가?

마틴은 진화적 설계가 일어나는지 파악하는 것이 어려운 일이라고 한다. 최근에는 프로그램 구조에 대해서 정량적/객관적 측정방법도 제안이 되고 있다. 하지만, 마틴은 이 부분은 주관적인 사실 정성적/주관적 측정이 되어야 하는 부분이라고 주장한다. 개발자가 아닌 이해당사자들은 이 부분에 대해서 이해하기 어려울 것이다. 고객의 경우를 생각한다면 자신들이 지불하고 있는 소프트웨어가 이 후에 기능을 추가하려면 더 많은 비용이 들 것인지 아닌지 알 수 없다는 것이다.

 

마틴은 구체적인 방법 대신 몇가지 제안을 한다.

  • 개발자의 이야기를 들어 보자. 코드베이스가 변경하기 어렵다고 불평한다면, 이를 심각하게 받아들이고 문제를 해결할 시간을 주어야 한다.
  • 얼마나 많은 코드가 버려지고 있는지 살펴 보자. 건강한 리팩토링을 하고 있다면 꾸준히 나쁜 코드는 삭제되고 있다. 버려지는 코드가 없다면 리팩토링이 충분하지 않다는 것이 거의 확실하다.

이러한 제안에도 불구하고 이 지표 또한 남용될 수 있다. 하지만, 우수한 개발자들의 의견은 매우 가치가 있다고 마틴은 주장한다.

 

참고 문헌

[1] Martin Folwer, "Is Design Dead?", https://martinfowler.com/articles/designDead.html

[2] 마틴 파울러, "리팩터링 2판 (리팩토링 개정판) - 코드 구조를 체계적으로 개선하여 효율적인 리팩터링 구현하기", 한빛미디어, 2020, 역자 남기혁

+ Recent posts