이번 컨퍼런스에서 Refactoring 이란 주제를 통해 설계와 소프트웨어의 가치에 대해 이야기 해 보는 세션을 진행했습니다. 사실 제가 해당 세션을 통해 전달하고자 한 것은 리팩토링 자체 보다는 이 주제를 매개로 소프트웨어와 개발에 대한 이야기를 하고 싶었습니다.

본 포스트를 통해서 해당 내용을 다시한번 정리 해 보도록 하겠습니다.

리팩토링(Refactoring) 이란?

개발 직무를 수행하는 분 중에 리팩토링이라는 용어를 처음 접하는 분은 아마도 찾기 힘들정도로 보편적으로 알려진 개념중에 하나일 것입니다. 하지만 세션 중 질문을 통해 볼 수 있었듯이 여러분 각자가 생각하는 리팩토링의 정의나 리팩토링이라는 용어가 주는 무게감이 다를 수 있을거라 생각합니다.
마틴 파울러Martin Fowler가 이와 관련 된 주제를 Refactoring 이라는 제목의 책으로 출간하기 전 까지는 리팩토링에 대한 시도와 연구가 활발히 이루어지던 스몰토크Smaltalk 커뮤니티에서도 이해의 차이가 많이 있었습니다.

마틴 파울러는 그의 저서에서 리팩토링의 정의를 다음과 같이 하고 있습니다:

  • [명사] 소프트웨어의 보여지는 동작은 그대로 유지한 채, 코드를 이해하고 수정하기 쉽도록 내부 구조를 변경하는 기법.
  • [동사] 소프트웨어의 보여지는 동작은 그대로 유지한 채, 여러 가지 리팩토링 기법을 적용해서 소프트웨어를 재구성 하다.

— Martin Fowler

1999년도에 초판이 출간 된 이후로도 수많은 저자들이 리팩토링이란 주제를 다루었지만 동작을 보존한 채 구조를 변경한다는 핵심 개념은 모두 공유하고 있습니다. 동작의 변화없이 코드의 구조를 더 나은 방향으로 변경하는 이 행위는 설계의 개선으로 간주할 수 있습니다.

리팩토링 ≒ 소프트웨어 설계의 개선

즉, 우리는 반복적인 리팩토링을 통해서 소프트웨어의 설계를 점진적으로 개선하게 되는 결과를 얻어낼 수 있게 됩니다.

그러면 이 리팩토링은 언제 수행하는 것이 적절할까요?

리팩토링 시기

우리는 직무 수행과정에서 종종 리팩토링을 두고 저울질 하는 경우를 보게 됩니다. 비지니스 이해관계자가 요구사항을 가져오면, 그 요구에 대응하기 위한 리팩토링이 선행되어야 한다는 식의 피드백을 종종 접하게 되죠. 그러한 경우 보통 리팩토링의 추정 작업비용이 클 확률이 높습니다. 가볍게 수행 가능한 리팩토링이라면 그렇게 대응할 이유가 없기 때문이죠.

이렇게 일정을 잡고 계획을 해야하는 계획된 리팩토링의 경우는 프로젝트의 상황에 따라 시기가 좌우되거나 심지어는 아예 진행되지 못하게 될 수 있지만, 가볍고 더 작은 단위의 리팩토링의 경우에는 수시로 진행할 수도 있습니다.

일찍 리팩토링하고, 자주 리팩토링하라. 1

— David Thomas & Andrew Hunt

그렇다면 얼마나 작은단위여야 수시로 진행가능할까요? 바꾸어 말하면, 수시로 리팩터링을 하기 위해서는 얼마나 작고 가볍게 리팩터링해야 할까요?
조금 더 명확하게 판단하기 위해, 저는 소프트웨어의 경제적 가치에 대해 먼저 이야기 해 보고자 합니다.

소프트웨어의 경제적 가치

제가 경영 일원으로써, 또 개발 실무자로써 암묵지로만 가지고 있던 소프트웨어와 비지니스의 역학관계에 대한 이해가 있었습니다. 명확한 개념이나 적절한 비유로 설명하기 힘든 아쉬움을 켄트벡Kent Beck이 그의 최근 저서에서 금융 공학을 통한 설명으로 해소시켜 주었는데 그 중 일부를 빌려서 이야기 해 보겠습니다.

현재가치와 순현재가치

우리가 가장 보편적으로 가치를 측정하는 척도이자 가치교환의 수단으로 쓰는 화폐의 대표적 예인 돈은 시간에 따라 가치가 달라집니다. 물가의 변동이나 이자율 등을 고려하면 매일 가치가 다르다고 볼 수 있습니다. 켄트벡의 말을 의역하자면, 오늘의 1만원은 내일의 1만원 보다 가치있습니다.
그렇다면 미래의 특정시점에 일정한 금액은 오늘의 가치로 환산하면 할인이 되게 될 것입니다. 이것을 금융학에서는 현재가치라고 합니다.

$$ PV = \frac{FV} {(1+r)^n} $$

  • PV: 현재가치
  • FV: 미래가치
  • r: 할인율(이자율)
  • n: 기간

이것을 미래 시점까지 발생하는 다양한 순편익 현금흐름을 고려하여 더 정교하게 계산한 것을 금융학에서 순현재가치라고 합니다.

$$ NPV = \sum_{t=1}^n\frac{CF_t} {(1+r)^t}-IC $$

  • NPV: 순현재가치
  • CF: 현금 흐름
  • r: 할인율
  • n: 기간
  • IC: 초기 투자 비용

화폐의 현재가치가 미래의 가치보다 높다는 것을 이해하셨다면 같은 화폐를 나중에 쓸수록 낮은 가치로 쓰게 되는 것이고, 빨리 얻을수록 높은 가치를 얻게 된다는 것이 이해 되실겁니다.

버는 것은 빨리하고, 쓰는 것은 가능한 미룬다 2

— Kent Beck

리팩토링 시기에대해 다시 고민해 보자면, 리팩토링을 하는 것(투자)을 이른시기에 혹은 수시로 하는것이 도움이 될까요? 리팩토링보다 기능추가를 먼저해서 수익시점을 당기는 것이 더 나을까요?

다음 주제와 함께 조금 더 고민 해 봅시다.

금융 옵션과 옵션 가격

금융학에는 금융 옵션이란 개념이 있습니다. 금융 옵션이란 미래의 특정 시점 또는 그 이전에 특정 기초자산을 정해진 행사 가격으로 사고 팔 수 있는 권리를 뜻합니다. 여기서 살 수 있는 권리를 콜옵션Call Option이라고 하고, 팔 수 있는 권리를 풋옵션Put Option이라고 합니다.

  • Call Option: 매수 권리
  • Put Option: 매도 권리

예를 통해 좀 더 쉽게 이해해 봅시다.

어느 영화관의 영화관람권 가격이 1만원이라고 가정해 봅시다. 이 영화관에서 7월 1일날 당일 이벤트로 7월 31일날 사용 가능한 교환권을 영화관람권 가격보다 30% 할인 된 금액인 7천원에 판매를 하는경우 이 교환권을 산 사람은 7월 31일에 싼 가격으로 영화관람권을 얻을 수 있게 됩니다.
이 경우 교환권은 7월 1일에 발행 되었고 7월 31일이 만기일인 기초자산 영화관람권에 대한 콜옵션에 해당합니다.

다른 한가지 예로 우리나라에 흔한 선분양 아파트의 분양권을 생각해 볼 수 있습니다. 2년 후에 입주가 가능한 아파트 분양권은 기초자산 아파트에 대한 취득권리로 역시 콜옵션에 해당합니다.

기초자산이 아닌 이 옵션 자체에도 가격이 있는데, 발행시점뿐만 아니라 옵션 자체를 거래할 수 있습니다. 앞의 교환권을 중고장터에서 거래하거나 분양권을 부동산에서 거래하는 것이 옵션의 거래에 해당한다고 볼 수 있습니다. 옵션이 거래 가능하다는 것은 옵션 자체에 부가가치가 존재한다는 뜻입니다.

켄트벡은 그의 저서 Tidy First? 에서 설계(리팩토링)를 이후의 동작 변경을 ‘구매’하는 ‘옵션’에 대해 지불하는 프리미엄으로 설명합니다. 즉 리팩토링이란 행위가 새로운 옵션을 계속 만들어 내는 행위로 설명됩니다.

나중에 더 벌기 위해, 지금 써야 한다 2

— Kent Beck

하지만 저는 그 책을 통해 리팩토링을 조금 다른 관점에서 보게 되었습니다. 다음 개념을 먼저 이해해 봅시다.

기초자산 가격과 옵션 가격

금융공학에는 옵션의 가치를 평가하는 방법중에 유명한 블랙-숄즈 모델Black-Scholes Model이 있습니다.
이 모형의 콜옵션 가격을 계산하는 방정식은 다음과 같습니다:

$$ C = S_0N(d_1)-X_e^{rT}N(d_2) $$

where:

$$ d_1 = \frac{\ln(\frac{S_0}{X})+(r+\frac{1}{2}σ^2)T}{\sqrt[σ]{T}} $$

$$ d_2 = d_1-\sqrt[σ]{T} $$

  • C: 콜옵션 가격
  • σ: 기초자산 가격 변동성

이 복잡한 수식에서 다른 부분은 이해하지 않더라도 콜옵션의 가격과 기초자산 가격 변동성간의 상관관계를 눈여겨 보시면 기초자산 가격 변동성이 높아질수록 콜옵션의 가격이 상승한다는 것을 이해하실 수 있으실 겁니다.

앞의 예에서 기초자산 가격변동성이 매우 낮은 영화관람권의 경우에는 교환권이 중고장터에서 거래될 때 원 구매가보다 비싸게 거래될 확률이 낮지만 가격변동성이 매우 높은 아파트의 경우에는 분양권 프리미엄이 엄청나게 높게 형성될 확률이 높은것과 같은 이치입니다.

저는 설계를 개선하는 행위를 기초자산인 기존 코드베이스를 변경이 쉽고 유연하게 만드는 행위로 기초자산의 가치가 더 높아질 가능성인 변동가능성을 높이는 행위라 생각합니다. 미래에 더 나은 가치를 가지게 될 소프트웨어 혹은 그 소프트웨어 개발팀에 투자하는 것은 마치 콜옵션을 구매하는 것과 같은것입니다. 위부 투자사에서 개발사의 가치를 평가할때도, 개발사의 경영진이 개발조직의 가치를 평가할때도 유사한 논리가 적용됩니다.
즉 소프트웨어 설계를 개선하는 것은 소프트웨어 개발주체의 가치를 높이는 것과 동일한 결과를 가져옵니다.

앞의 이야기를 다 이해하지 못하더라도 이 모든것을 함축한 가상의 예를 통해 손쉽게 추론 가능합니다.

비지니스 이해관계자가 가져온 요구를 즉시 수용해서 1달 내에 구현할 수 있는 개발팀A와 똑같은 요구를 리팩토링 1주일까지 더해서 2달이 되어도 겨우 구현할 수 있는 개발팀B가 같은 회사내에 있는 경우 의심의 여지없이 개발팀A가 더 높은 급여와 더 나은 대우를 받게 될 것입니다.

조금 시각을 바꿔서, 그 개발팀A와 개발팀B는 사실 완전히 같은 개발팀이라고 생각 해 봅시다. 그들이 코드를 다루면서 내리는 매일의 의사결정의 결과로 만들어 진 상태에 따라 A와 같은 상황이 될 수도있고 B와 같은 상황이 될 수도 있습니다.

이제 다시돌아가서, 리팩토링은 언제해야 할까요?

코드 정리

리팩토링의 시기는 여전히 혼란스러울 수 있습니다. 어떻게 더 일찍, 더 자주 리팩토링할 수 있을까요?
리팩토링을 간단한 코드정리 작업으로 생각하고 접근 해 봅시다. 실제로 유명한 리팩토링 기법의 상당수는 간단한 코드정리 행위에 해당합니다.

  • 이름 정리
  • 순서 정리
  • 분류하기

이 세가지로 시작해 봅시다. 코드가 정리되어 나가고 명료해질수록 점점 더 과감한 코드정리, 더 무자비한 리팩토링 3을 수행할 수 있게 됩니다.

보이스카웃 규칙 4처럼 항상 코드를 수정하기 전보다 깨끗하게 만들어 두고, 깨진 창문 5이 방치되지 않도록 눈에 보이는 정리대상 코드를 그냥두지 마세요.


같이 다루고 싶었으나 다루지 못한 내용

해당 주제와 연관지어 다루고 싶었으나 세션의 시간 제약상 다루지 못한 내용들은 참조서적 안내로 대체하겠습니다. 모두 이번 주제와 직간접적으로 연관이 있는 내용들을 다루고 있습니다.

Refactoring - Martin Fowler

사실 세션 제목이 리팩토링임에도 주제는 조금 어긋난 내용을 다루었습니다. 그래서 리팩토링 기법에 대한 설명이나 예시는 완전히 배제되어 있는데, 이에 대해 더 깊이 알고 싶다면 이 책을 참조하는 것으로 충분합니다.

Tidy First? - Kent Beck

세션 내용을 구성하는데 직접적인 영감을 제공한 책이며, 주제에 가장 근접한 내용의 책입니다. 리팩토링의 선구자인 켄트벡의 시각에서 설계와 개발을 보는 데 도움이 됩니다.

Clean Code & Clean Architecture - Robert C. Martin

리팩토링과 설계에 관한 주제를 로버트 마틴의 시각으로 볼 수 있습니다. 추가적으로 Clean Craftsmanship 을 같이 본다면 마틴의 철학을 이해하는데 더 도움이 됩니다.

Test-Driven Development - Kent Beck

리팩토링에는 테스트가 매우 중요한 역할을 합니다. 리팩토링에 대한 안전을 보장받으려면 리팩토링 전에 테스트를 먼저 작성해야 합니다. 이 책은 애초에 그러한 상황이 생기지 않게 모든 구현에 앞서 테스트를 먼저 작성하고 구현과 리팩토링이 뒤따르도록 하는 방법을 알려줍니다.

Extreme Programming - Kent Beck

TDD에서 더 나아가 페어프로그래밍Pair Programming등 ‘Extreme’한 실천법과 그 배경 철학을 배워볼 수 있는 책입니다.

Working Effectively with Legacy Code - Michael C. Feathers

리팩토링에는 테스트가 필요하지만, 테스트를 작성하려면 리팩토링을 해야 하는 코드가 있습니다. 닭이 먼저일까요 달걀이 먼저일까요? 셀메이트 레거시 코드가 떠오르나요? 이런 레거시 코드를 다루는 방법을 깊이있게 다루는 책입니다.

Code Complete - Steve McConnell

개발을 처음 접한 건 12살 초등학생때였는데, 고등학교 때까지는 무엇인가를 만들어 내는 그 창조에만 재미를 느끼고 집중했습니다. 20살이 되어서야 처음으로 동작이 아니라 코드를 쓰는법에 대한 고민을 하게 만들어 준 책으로 가독성 뿐만 아니라 저수준의 구조적인 원리를 기반으로 한 효율적인 코드 작성에 대한 방법도 접할 수 있습니다.


  1. 실용주의 프로그래머The Pragmatic Programer Tip 47, David Thomas & Andrew Hunt ↩︎

  2. Tidy First?, Kent Beck ↩︎ ↩︎

  3. Extreme Programming Explained, Kent Beck ↩︎

  4. 캠핑장을 발견했을때 보다 깨끗이 하고 떠나라. (https://www.oreilly.com/library/view/97-things-every/9780596809515/ch08.html↩︎

  5. 깨진 유리창 이론 (https://en.wikipedia.org/wiki/Broken_windows_theory↩︎