[Reading Book]Refactoring(1)

2장 리팩토링의 원리

리팩토링의 중요 원리와 리팩토링을 사용할 때 생각해 봐야 할 문제들을 살펴보자.

2.1 리팩토링의 정의

  • Refactoring(명사형) - 소프트웨어를 보다 쉽게 이해할 수 있고, 적은 비용으로 수정할 수 있도록 겉으로 보이는 동작의 변화 없이 내부 구조를 변경하는 것

  • Refactor(동사형) - 일련의 리팩토링을 적용하여 겉으로 보이는 동작의 변화 없이 소프트웨어 구조를 바꾸다.

  • 리팩토링의 목적은 소프트웨어를 보다 이해하기 쉽고, 수정하기 쉽도록 만드는것이다. 그리고 겉으로 보이는 소프트웨어의 기능을 변경하지 않는다.

  • 두개의 모자
    • 소프트웨어 개발을 할 때, 기능 추가와 리팩토링 두 작업에 대한 구분을 해야한다.
    • 기능을 추가할 때는 기존 코드를 건드려서는 안되고 단지 새로운 기능만 추가해야한다.
    • 리팩토링을 할 때는 기능을 추가해서는 안되고, 단지 코드의 구조만 신경써야한다.

2.2 왜 리팩토링을 해야 하는가?

  1. 리팩토링은 소프트웨어의 디자인을 개선시킨다.
    • 코드를 수정함에따라 중복된 코드가 늘어나게 되고 원래 구조를 잃게 된다.
    • 리팩토링을 통해 이런 구조를 정리하여 디자인을 개선할 수 있다.
  2. 리팩토링은 소프트웨어를 더 이해하기 쉽게 만든다.
    • 🙋‍♂️ 대부분의 개발자는 코드를 작성하는 시간보다 읽는 시간이 더 많다. 리팩토링을 통해 디자인을 개선하고 읽기 쉽게 만든다면, 소프트웨어 구조를 더 쉽게 이해할 수 있다.
  3. 리팩토링은 버그를 찾도록 도와준다.
    • 코드를 리팩토링 하면, 코드가 무슨 작업을 하는지 깊이 이해할 수 있고, 버그를 쉽게 찾을 수 있다.
  4. 리팩토링은 프로그램을 빨리 작성하도록 도와준다.
    • 기능 추가외에 리팩토링까지 하면 개발 속도가 더 늦어질 수 있다고 생각 할 수 있다.
    • 하지만 리팩토링을 통해 디자인이 잘 확립이 되면 기능 추가를 위해 코드를 계속 읽는 시간이 줄어들고 결국 개발 속도를 향상시키는데 도움을 준다.
  • 리팩토링이 소프트웨어의 모든 문제점을 해결하는 만병통치약은 아니지만 유용한 도구인것은 확실하다.

2.3 언제 리팩토링을 해야 하는가?

  1. 삼진 규칙
    • 처음엔 그냥 하고, 두번째로 비슷한 것을 하게되면 그냥 중복되게 하고, 세번째로 비슷한 것을 하면 리팩토링한다.
  2. 기능을 추가할 때 리팩토링을 하라
    • 수정해야 할 코드에 대한 이해를 돕기 위해
    • 한번 리팩토링을 해놓으면 기능을 추가하기 더 쉬워진다.
  3. 버그를 수정해야 할 때 리팩토링을 하라
    • 버그가 있다는 것을 몰랐을 정도로 코드가 명확하지 않다는 뜻이다.
  4. Code Review를 할 때 리팩토링을하라
    • 내 코드가 나에게는 명확할 수 있지만 다른 사람들에게는 아닐 수 있다.
    • 코드 리뷰를 통해 더 좋은 아이디어를 제안할 기회가 된다.
    • 짝 프로그래밍을 통해 코드 리뷰와 리팩토링을 진행하는것이 좋다.

2.4 관리자에게 뭐라 말해야 하나?

  • 관리자에게 리팩토링 한다는 사실을 말하지 않는것이 좋다.
  • 개발자가 할 일은 효과적인 소프트웨어를 가능한 빨리 만들어내는 것이다.
  • 리팩토링은 개발 속도 향상에 큰 도움을 준다.
    • 기능을 추가 할 때 속도가 빠르다.
    • 버그 수정 할 때 소프트웨어 작동을 빠르게 이해할 수 있다.

2.5 리팩토링 관련 문제들

  1. 데이터베이스
    • 대부분의 애플리케이션은 데이터베이스와 결합되어 있기 때문에 데이터베이스의 변경이 어렵다.
    • 데이터베이스와 객체 모델간의 의존성을 최소화하려고 해도, 데이터베이스를 변경하면 데이터를 이전해야하는데 시간이 오래걸리고 위험성이 높다.
  2. 인터페이스 변경
    • 리팩토링의 대부분이 인터페이스를 변경한다.(간단한 메서드 이름 변경이라도)
    • 공표된 인터페이스라면 더 이상 안전하게 인터페이스를 수정 할 수 없다.
      • 공표된 인터페이스를 수정하면 나는 일단 사용할 수 있지만 다른곳에서는 공표된 인터페이스를 그대로 사용하기 때문에 일치하지가 않기 때문이다.
    • 🙋‍♂️ 공표된 인터페이스를 상속하는 나만의 인터페이스를 만들고 그에 대한 구현 클래스를 만들면 되지 않을까? 이 과정이 복잡하다는 얘기일까?
  3. 리팩토링이 어려운 디자인변경
    • 🙋‍♂️ 내가 회사를 들어갔다고 가정하자. 이미 회사에서 사용하고 있는 설계구조가 있을텐데 내가 “아 냄새나는 코드네 수정해야지”라며 확립 되어있는 디자인을 리팩토링 할 수 없는 없다. 또는 리팩토링 하는데 큰 비용이 드는경우가 있을 수 있다.
  4. 언제 리팩토링을 하지 말아야 하는가
    • 기존 코드 구조가가 매우 엉망인 경우에는 리팩토링을 하는 것보다 코드를 새로 작성하는 것이 더 쉬울 수 있다.
    • 마감일이 다가오는 경우에는 리팩토링하지 않고 미루는것이 더 좋을 수도 있다.

2.6 리팩토링과 디자인(설계)

  • 리팩토링은 설계를 보완하는 특별한 역할을 한다.
  • 리팩토링을 하지 않는다면, 처음부터 정확한 디자인을 해야한다는 부담이 있다.
  • 리팩토링을 하는 경우 강조점이 바뀐다. 정확한 솔루션보다 적절한 솔루션을 찾는다.
  • 결과적으로 디자인이 단순해진다.
  • 🙋‍♂️ 나는 마틴 파울러와 같은 생각을 했었다. 간단한 문제 푸는 과정에서도 구현전에 머리속으로 먼저 구현해봤다. 그게 ‘설계’라고 하기에는 다소 무리가 있다고 생각했다. 왜냐하면 설계는 완벽해야한다고 생각했기 때문이다.
  • 🙋‍♂️ 그런데 리팩토링과, TDD를 공부하며 가장 크게 느낀것은 설계는 완벽할 수 없으며 계속 변해야한다는 것이다. 처음부터 완벽한 디자인을 설계하려고 하면 설계하는 비용도 들고, 변화에 대처하기도 힘들다. 그러나 리팩토링을 통해 “이 시점에서 더 간결하고 읽기 좋게 구현할 방법이 뭐가있을까?”를 생각해보면 자연스럽게 좋은 설계로 갈 수 밖에 없다.

2.7 리팩토링과 퍼포먼스(성능)

  • 소프트웨어를 더 이해하기 쉽게 만들기 위해 리팩토링을 하는데, 이는 종종 프로그램을 더 느리게 하는 원ㅇ니이 될 수 있다.
  • 단편적으로 보면 소프트웨어를 더 느리게 할 수 있지만, 소프트웨어에 대한 퍼포먼스 튜닝을 더 쉽게 할 수 있도록 만든다.
  • 퍼포먼스 튜닝을 쉽게 할 수 있기 때문에 최적화 단계에서 쉽게 튜닝을 할 수 있다.
  • 🙋‍♂️ 아직 나는 성능 향상을 느끼지는 못했다. inline으로 끝낼 수 있는 것을 지역변수로 선언해서 더 쉽게 읽을 수 있는 수준으로 리팩토링을 진행하고 있기 때문이다. 그런데 이런 작은 성능은 요즘 단계에서 무시할 수 있는 수준의 성능 차이라고 생각한다.
  • 🙋‍♂️반면 리팩토링 과정에서 이중 for문을 사용하는 경우에서 for문 하나로 해결할 수 있을까 고민을 하게되고 실제로 잘 적용되기도 한다.

댓글남기기