패턴을 활용한 리팩터링 1장: 이 책을 쓴 이유

Raymond Yoo·2021년 12월 12일
0

Refactoring to Patterns, 1st read

과도한 설계

  • 코드를 필요 이상으로 융통성 있게 또는 정교하게 만들 때, 이를 과도한 설계라고 한다. 어떤 프로그래머들은 시스템에 대한 미래의 요구사항을 알고 있다고 믿기 때문에 과도하게 설계한다. 오늘 설계를 좀 더 융통성이 있고 정교하게 해두어, 내일의 요구사항을 수용할 수 있게 하는 것이 최선이라고 생각하는 것이다. 그럴싸하게 들린다. 여러분이 무당이라도 된다면 말이다.
  • 그러나 예상이 틀렸다면 귀중한 시간과 비용을 낭비한 꼴이 된다. 과도하게 융통성 있고 필요 이상으로 정교하게 설계하는 데 며칠 또는 몇 주의 시간을 허비하느라, 정작 새로 필요한 기능을 추가하거나 결함을 고칠 시간은 줄어든 것이다.
  • 필요할 것이라 예상하고 만들었지만 전혀 쓰이지 않는 코드에 대해서는 또 어떤 일이 일어나는가? 그런 코드는 절대 없어지지 않는다. 그 코드를 제거하는 것이 귀찮거나 또는 언젠가 필요해질지도 모른다고 기대하기 때문이다. 이유야 어떻든, 지나치게 융통성 있거나 불필요하게 정교한 코드가 쌓이면, 자신이나 팀에서 같이 일하는 다른 프로그래멀(특히 신참들)이 모두 필요 이상으로 크고 복잡한 코드를 기반으로 작업해야 한다.
  • 이를 완화하기 위해 시스템을 영역별로 나눠 작업하기도 한다. 이렇게 하면 작업이 더 쉬워질 것 같지만, 필요로 하는 기능을 이미 구현한 코드가 있는지 찾아보지 않고 모두들 자신이 맡은 영역에서만 작업하기 때문에 코드 중복을 양상하는 부작용이 나타날 것이다.
  • 프로그래머가 과도한 설계를 하는 주된 이유는 아마 나쁜 설계에 빠져 옴짝달싹 못하는 것을 원치 않기 때문일 것이다. 나쁜 설계는 코드 깊숙한 곳까지 얽혀 개선을 매우 어렵게 할 수 있다. 나도 그런 경험이 있다. 패턴을 이용한 사전 설계가 내게 그렇게 매력적으로 보였던 것은 그런 이유 때문이다.

패턴 만능주의

  • 패턴을 처음 배우기 시작했을 때, 패턴은 객체지향 설계를 위한 융통성 있고 정교하며 심지어 우아하기까지 한 방법으로 보였다. 그래서 나는 패턴을 완전히 정복하고 싶었다. 많은 패턴과 패턴 언어를 철저히 공부한 다음, 내가 이미 구축한 시스템을 개선하거나 구축하려는 시스템의 설계를 공식화하는 데 사용했다. 이런 노력에는 좋은 결과가 있을 것 같았고, 내가 올바른 길을 가고 있다고 생각했다.
  • 그러나 시간이 지나면서 패턴의 강력함에 빠져 간단하게 작성할 수 있는 코드조차 괜히 복잡하게 만들게 되었다.
  • 이런 경험을 통해 나는 모든 것을 패턴으로 해결하려는 생각을 버리고, 작고 단순하고 이해하기 쉬운 코드를 작성하는 데 주의를 기울여야 한다는 것을 깨달았다.
  • 더 나은 소프트웨어 설계자가 되기 위해 열심히 패턴을 공부했지만, 진정으로 더 나아가기 위해서는 패턴에 대한 맹신을 접어야 했다.

미진한 설계

  • 과도한 설계보다는 미진한 설계가 훨씬 흔하다.
  • 미진한 설계를 했던 경험은 누구에게나 한 번 이상 있을 것이다. 나도 마찬가지다. 코드를 빨리 동작하도록 만들라는 극도의 재촉에 시달리고 있었기 때문일 수도 있다. 이것은 기존 코드의 설계를 개선하려는 우리의 노력에 대한 강력한 훼방꾼이 되곤 한다. 어떤 경우에는 코드의 수명이 그리 길지 않을 것임을 알기(또는 안다고 생각하기) 때문에 개선할 필요성을 의도적으로 무시하기도 한다. 때론 관리자가 나름대로 좋은 의도에서 '잘 돌아가는 것을 건드리지만 않으면' 우리 조직이 훨씬 경쟁력 있고 성공적일 것이라 설득하여 넘어가기도 한다.
  • 지속적으로 미진한 설계가 쌓이면 소프트웨어 개발은 결국 '빠르다가, 느려지고, 더 느려지는' 양상이 된다.

테스트 주도 개발과 지속적인 리팩토링

  • 테스트 주도 개발(TDD)과 지속적인 리팩토링은 나의 소프트웨어 개발 능력을 극적으로 향상시켰다. 이 두 실행지침을 실천하면 나와 내가 속한 조직이 과도한 설계나 미진한 설계에 시간을 허비하는 대신에 다양한 기능의 코드를 높은 품질로 적시에 생산할 수 있다는 것을 알게 됐다.
  • 테스트 주도 개발과 지속적인 리팩토링은 프로그램을 다음과 같은 대화로 바꿔, 기존 코드를 효율적으로 발전시킬 수 있도록 한다.

질문 - 테스트를 작성함으로써 시스템에 질문한다.
대답 - 테스트를 통과하는 코드를 작성해 질문에 대답한다.
정제 - 아이디어를 통합하고 불필요한 것은 제거하고, 모호한 것은 명확히해서 대답을 정제한다.
반복 - 다음 질문을 물어 대화를 계속한다.

  • 이런 프로그래밍 리듬은 나를 완전히 새로운 세계에 데려다 놓았다. 모든 상황에서 시스템이 작동하도록 설계하기 위해 생각하는 데 많은 시간을 보내는 대신 TDD를 통해 제대로 동작하는 주요 기능을 몇 초 또는 몇 분 만에 만들어 낸다. 그 다음, 리팩터링을 통해 필요한 수준의 정교함을 갖출 때까지 발전시킨다.
  • TDD와 지속적인 리팩터링에 대해 Kent Beck이 내건 슬로건은 '빨강, 초록, 리팩터링' 이다.
  1. 빨강. 코드가 해야 할 일을 예상하고 이것을 나타내는 테스트를 작성한다. 테스트를 통과하는 코드를 아직 작성하지 않았기 때문에 테스트는 실패할 것이다(빨간색으로 바뀐다).
  2. 초록. 테스트를 통과하도록 임시방편으로라도 프로그램을 작성한다(초록색으로 바뀐다). 이 단계에서는 코드 중복, 단순함, 명확한 설계 같은 것을 고민할 필요가 없다. 그런 설계는 나중에 모든 테스트를 통과한 후 더 좋은 설계를 맘 편하게 테스트할 수 있는 단계가 되면 그때에 가서 생각할 수 일이다.
  3. 리택터링. 테스트를 통과한 코드의 설계를 개선한다.
  • 말은 단순하지만, TDD와 지속적인 리팩터링은 프로그래밍 세계를 완전히 뒤집어버렸다. 경험이 적은 프로그래머는 '존재하지 도 않는 코드에 대한 테스트를 작성한다고? 임시방편으로라도 코드를 작성해 테스트를 통과하라고? 이거 완전히 비효율적이고 무계획한 소프트웨어 개발 방법이잖아?' 하고 생각할지도 모르겠다.
  • 실제로는 그와 정 반대다. TDD와 지속적인 리팩터링은 집중과 이완, 생산성을 극대화하는 간결하고 반복적이며 통제된 프로그래밍 스타일이다. Martin Fowler는 이를 '민첩한 느긋함' 이라고 표현했고, Ward Cunningham은 이를 테스트에 관한 것이라기보다는 지속적인 분석과 설계에 관한 것이라 설명했다.
  • TDD와 지속적인 리팩터링의 올바른 리듬을 배우려면 연습이 필요하다. TDD와 지속적인 리팩터링을 사용해 프로그램을 작성하는 많은 사람들이 다음과 같은 사실을 깨닫고 있다.

결함의 개수를 적게 유지하는 데 도움이 된다.
두려움 없이 리팩터링을 하는 데 도움이 된다.
더 단순하고 훌륭한 코드를 생산하는 데 도움이 된다.
스트레스를 상대적으로 덜 받고 프로그램을 작성하는 데 도움이 된다.

리팩터링과 패턴

  • 설계를 잘 하기 위해서 디자인 패턴 자체를 학습하거나 디자인 패턴이 하는 일을 이해하려는 노력은 코드를 개선하는 데 크게 도움이 되지 않을 확률이 높다. 주어진 설계 문제를 각 패턴이 다루는 문제와 대응시켜보는 것이 낫다. 왜 그럴까? 패턴은 문제를 풀기 위해 존재하며, 주어진 상황에서 패턴이 정말 도움이 되는지를 아는 것은 그 패턴이 어떤 문제를 푸는 데 도움을 주는지 이해하는 것과 관계가 깊기 때문이다.

발전적 설계

  • 더 훌륭한 소프트웨어 설계자가 되려면, 훌륭한 소프트웨어 설계가 어떻게 발전해왔는지 그 과정을 공부하는 것이 훌륭한 설계 자체를 공부하는 것보다 훨씬 가치있다. 그 발전 과정 속에 진짜 지혜가 숨어 있기 때문이다. 발전의 결과로 나온 구조도 도움이 되긴 하겠지만, 그 구조가 왜 그런 식의 설계로 발전했는지를 알지 못한다면, 다른 프로젝트에서 그것을 잘못 적용하거나 그 구조를 사용해 과도한 설계를 할 가능성이 커진다.
  • 설계를 발전시켜 나가는 방법을 배움으로써, 더 훌륭한 소프트웨어 설계자가 될 수 있고 과도하거나 미진한 설계를 하는 빈도를 줄일 수 있다. TDD와 지속적인 리팩터링은 발전적 설계의 핵심 실행지침이다. 패턴을 고려한 리팩터링을 수련하여 리팩터링 방법을 체화한다면 훌륭한 설계를 발전시킬 더 좋은 장비를 갖추게 되는 것이다.
profile
세상에 도움이 되고, 동료에게 도움이 되고, 나에게 도움이 되는 코드를 만들고 싶습니다.

0개의 댓글