Tidy First?


켄트 벡의 Tidy First?

[PART 1] 코드 정리법

  • 코드 정리를 리팩터링의 부분집합으로도 볼 수 있습니다.
  • 코드 정리는 작은 리팩터링입니다.
  • 무섭다면 작게 하세요. 두려움을 느끼지 않는 수준의 바로 그 단계가 가장 좋은 수준입니다.
  • 보호 구문

  • 중첩된 조건은 아래와 같이 정리할 수 있습니다.
  • if (조건1) return;
    if (조건2) return;
    ...코드...
  • 처음 두 줄은 도우미 메서드로 추출할 수 있습니다.
  • 안 쓰는 코드

  • 지워 버리세요.
  • 지웠다가 나중에 필요할 경우 어떡하지?라고 말할 수도 있습니다. 이런 걱정이라면 바로 형상 관리 도구가 해결해 줍니다.
  • 최악의 상황이 오더라도 언제든 되돌릴 수 있습니다.
  • 대칭으로 맞추기

  • 코드는 유기체처럼 성장하므로 같은 문제라도 시대와 사람에 따라 여러 가지 방식으로 코드를 작성할 수 있습니다.
  • 한 가지 방식을 선택해서 정합니다. 다른 방식으로 작성한 코드를 선택한 방식으로 고칩니다.
  • 때로는 공통성이 있는데도 세부 사항에 묻혀 드러나지 않습니다. 비슷해 보이지만 같지 않은 루틴을 찾아냅니다. 그러고 나서 같은 부분들 속에 다른 부분이 끼어 있다면 분리합니다.
  • 새로운 인터페이스로 기존 루틴 부르기

  • 기존 인터페이스 때문에 어렵거나, 복잡하거나, 혼란스럽거나, 지루해지곤 합니다. 이 모든 경우에 호출하고 싶은 인터페이스를 새롭게 구현해서 호출하세요.
  • 이처럼 새롭게 구현한 통로 인터페이스는 소프트웨어 설계에서 작은 단위로 중추적 역할을 합니다.
  • 읽는 순서

  • 읽기 좋은 순서로 다시 정렬하면, 그 순서대로 코드를 만날 수 있습니다. 코드를 읽을 떄는 독자의 입장이 되어보세요.
  • 완벽한 순서는 없습니다. 그러나 다른이에게 정렬된 코드를 선물하세요.
  • 응집도를 높이는 배치

  • 변경해야 할 동작을 찾았더니 여러 곳에 흩어져 있는 코드를 함께 바꿔야 한다는 걸 알면 불편합니다.
  • 두 루틴에 결합도가 있으면 서로 옆에 두세요.
  • 결합도를 제거할 수 있다면 그렇게 하지만, 여러 가지 이유로 결합도 제거가 어려울 수 있습니다.
  • 때로는 응집도를 조금 개선해서 코드가 명확해지면, 결합도 제거를 막고있던 장막이 걷힐 수 있습니다.
  • 설명하는 변수

  • 처음에는 작게 시작했더라도, 시간이 흐르면 코드는 반드시 커집니다. 그러다가 돋보기까지 동원해야만 무슨 내용인지 알게 되는 지경에 이릅니다.
  • 표현식의 의도가 드러나도록 변수 이름을 만들어 할당해 보세요.
  • 설명하는 상수

  • 상징적인 상수를 만드세요. 리터럴 상수로 사용된 곳은 상징적인 상수로 바꿉니다.
  • 같은 리터럴 상수가 두 곳에서 나타날 때는 다른 의미로 쓰이는지 확인하세요. 그러니 다음과 같은 빈약한 의미를 가진 코드 정리는 도움이 되지 않습니다.
  • const ONE = 1;

    명시적인 매개변수

  • foo 함수를 나누어 명시적 매개변수 정리를 적용할 수 있습니다.
  • function foo(params) {
    foo_body(params.a, params.b)
    }
    function foo_body(a, b) {
    ...a... ...b...
    }
  • 매개변수를 명시적으로 드러나게 만든 다음, 함수를 연쇄적으로 호출할 수 있게 준비하세요.
  • 비슷한 코드끼리

  • 긴 코드 덩어리를 읽다가 아, 이 부분은 이렇게 하고, 저 부분은 저렇게 하는구나라고 구분이 될 때는 두 부분 사이에 빈 줄을 넣어 분리합시다.
  • 도우미 추출

  • 목적이 분명하고 나머지 코드와는 상호작용이 적은 코드 블록을 만날 때가 있습니다. 그 코드 블록을 추려내고, 도우미로 추출한 후에 이름을 붙입니다.
  • helper() {
    ...바꾸려는 코드...
    }
    routine() {
    ...그대로 두는 코드...
    helper()
    ...그대로 두는 코드...
    }

    하나의 더미

  • 필요한 만큼의 코드를 하나의 더미처럼 느껴질 때까지 흩어진 코드를 모으세요. 그러고 나서 깔끔하게 정리하세요.
  • 코드를 만드는 데, 가장 큰 비용이 들어가는 일은 코드 작성이 아니라 읽고 이해하는 데 드는 비용입니다.
  • 작은 코드 조각을 지향하는 목적은 코드를 한 번에 조금씩 이해할 수 있도록 하는 것입니다. 하지만 때때로 이 과정이 잘못될 수 있습니다. 작은 코드 조각들이 서로 교류하는 방식은 코드를 더 알기 어렵게 합니다. 명확성을 되찾으려면, 먼저 코드를 한데 모아서 이해하기 어려운 부분은 추출해서 새롭게 정리해야 합니다.
  • 설명하는 주석

  • 코드를 읽다가 아, 이건 이렇게 돌아가는 거구나!라는 생각이 드는 순간을 아시죠? 바로 그 순간이 소중한 순간입니다. 기록하세요.
  • 결국, 이를 제거하는 방법을 배워야 하겠지만, 그 때까지는 주석을 달아서 결합도 문제를 미리 지적해 두는 것이, 모래 속에 묻듯 그냥 두는 것보다 훨씬 나을 것입니다.
  • 불필요한 주석 지우기

  • 코드만으로 내용을 모두 이해할 수 있다면 주석은 삭제하세요.
  • 주석이 완전한 중복이라면 삭제하세요.

  • [PART 2] 관리

    코드 정리 구분

  • 동작 변경(B)과 구조 변경(S)을 구분하여야 한다.
  • 동작 변경과 구조변경에 순서를 부여한다.
  • 작은 PR로 나눌지 또는 한 개의 PR로 처리할지는 장단점이 있는 선택이다.
  • 연쇄적인 정리

  • 작은 단계로 나누어 코드를 정리하는 방식을 사용해보자.
  • PART 1에서 등장한 Tidy를 단계적으로 적용해보자.
  • 너무 많이, 빠르게 변경하지 않도록 주의하자.
  • 코드 정리의 일괄 처리량

  • 코드 정리 비용을 줄이고자 한다면 코드 정리 개수를 늘려서 동작 변경에 소용되는 비용을 줄이자.
  • 리듬

  • 코드 정리의 리듬
  • 한 번의 코드 정리에 한 시간을 넘지 않는다.
  • 얽힘 풀기

  • 우리는 컴퓨터에 지시하는 것 뿐아니라 컴퓨터에 지시하려는 의도를 다른 사람들에게도 설명해야 한다.
  • 실타래를 풀려면 실이 엉켜 있다는 사실을 알아차려야 시작할 수 있다.
  • 실타래를 풀어야 할 필요성을 더 일찍 깨달을수록 작업량은 적어질 것이다.
  • 진행 중인 작업을 버리고, 코드 정리를 선행하는 순서로 다시 시작해볼 수 있다.
  • 코드 정리 시점

  • 아예 정리하지 않는다.
  • 나중에 정리하기
  • 동작 변경 후에 코드 정리
  • 코드 정리 후에 동작 변경
  • 요약

    다음 상황에는 코드 정리를 하지 마세요.

  • 앞으로 다시는 코드를 변경하지 않을 때
  • 설계를 개선하더라도 배울 것이 없을 때
  • 다음 상황에서는 나중으로 정리를 미루세요.

  • 정리할 코드 분량이 많은데, 보상이 바로 보이지 않을 때
  • 코드 정리에 대한 보상이 잠재적일 때
  • 작은 묶음으로 여러 번에 나눠서 코드 정리를 할 수 있을 때
  • 다음 상황에서는 동작 변경 후에 정리하세요.

  • 다음 코드 정리까지 기다릴수록 비용이 더 불어날 때
  • 코드 정리를 하지 않으면 일을 끝냈다는 느낌이 들지 않을 때
  • 다음 상황에서는 코드 정리 후에 동작 변경을 하세요.

  • 코드 정리를 했을 때, 코드 이해가 쉬워지거나 동작 변경이 쉬워지는 즉각적인 효과를 얻을 수 있을 때
  • 어떤 코드를 어떻게 정리해야 하는지 알고 있을 때

  • [PART 3] 이론

    요소들을 유익하게 관계 맺는 일

  • 소프트웨어 설계의 의미는 요소들을 유익하게 관계 맺는 일
  • 소프트웨어 설계자는 요소들을 유익하게 관계 맺는 일을 한다.
  • 구조와 동작

  • 구조는 동작처럼 또렷하게 드러나지 않는다.