• 2021. 12. 21.

    by. 문익점

    반응형

    리팩터링 2판(마틴 파울러 저)을 읽고 작성한 리뷰입니다.

    이 책을 읽게 된 계기

    이번 년도에 프론트엔드 신입으로 입사하게 됬다. 새로 시작하는 프로젝트를 맡게됬고 같이 작업하는 프론트엔드 개발자 분도 신입이라 개인 프로젝트를 만들었던 방식 그대로 웹 프론트엔드를 작업했다. 현업을 경험 한 사람은 알겠지만 요구 사항은 수시로 변경되고 그에 따른 변화를 빠르게 반영해야 된다. 변화를 반영만 해서는 안되고 버그까지 잡아야 하기 때문에 코드가 수정이 쉬워야 하고 테스트가 가능해야 된다. 하지만 나는 전혀 이러한 코드를 생산 할 줄 몰랐으며 당연히 조그만한 변화에도 구조가 크게 변경되어야 했었고 버그는 일상이였다. 나는 그레서 더 나은 코드에 대해 고민하게 되었고 책을 하나 찾게 되었다. 바로 마틴 파울러의 리팩터링 2판이다.

    책에 대하여

    이 책은 효율적인 방식으로 리팩터링을 하는 법에 대하여 소개한다. 리팩터링은 코드의 기능(동작)은 바꾸지 않으면서 그 구조를 변화에 대해 대응하기 쉬운 구조로 개선하는 과정을 말한다. 이 과정을 통해 버그가 생길 가능성을 최소로 줄이면서 코드를 개선하고 정리할 수 있다. 즉 코드의 설계를 개선하는 일이다. 예시 코드들은 자바스크립트로 이루어져 있다. 첫 장부터 리팩터링에 대한 예시를 들어주고 그 방식이 필요한 이유 마지막엔 효율적인 방식의 리팩터링을 설명한다.

    1장 리뷰

    리팩터링이 처음이라면 1장을 읽으면 된다. 간단한 리팩터링 진행 절차를 같이 진행하면서 예시를 들어준다.

    간단한 첫 리팩터링 첫 단계

    책에서 간단한 영수증을 출력하는 코드를 보여준다.

    function statement(invoice, plays) {
      let totalAmount = 0;
      let volumeCredits = 0;
      let result = `청구 내역 (고객명: ${invoice.customer})\n`;
      const format = new Intl.NumberFormat("ko-kr", {
        style: "currency",
        currency: "KRW",
      }).format;
    
      for (let perf of invoice.performances) {
        const play = plays[perf.playID];
        let thisAmount = 0;
    
        switch (play.type) {
          case "tragedy": {
            thisAmount = 40000;
            if (perf.audience > 30) thisAmount += 1000 * (perf.audience - 30);
            break;
          }
          case "comedy": {
            thisAmount = 30000;
            if (perf.audience > 20)
              thisAmount += 10000 + 500 * (perf.audience - 20);
            thisAmount += 300 * perf.audience;
            break;
          }
          default:
            throw new Error(`알 수 없는 장르: ${play.type}`);
        }
    
        volumeCredits += Math.max(perf.audience - 30, 0);
        if (play.type === "comedy") volumeCredits += Math.floor(perf.audience / 5);
        result += `  ${play.name}: ${format(thisAmount / 100)} (${
          perf.audience
        }석)\n`;
        totalAmount += thisAmount;
      }
      result += `총액: ${format(totalAmount / 100)}\n`;
      result += `적립 포인트: ${volumeCredits}점\n`;
      return result;
    }
    
    export default statement;

    첫 장 부터 마틴 파울러에게 저격을 당했다. 처음 이 코드를 보았을 때 전형적인 나의 코드라서 놀랬다. 아마 초보 개발자라면 대부분 이런 코드를 작성 할 것이다. 이 책에서는 이러한 코드에 문제를 제기한다. 바로 이 코드는 청구서에 들어갈 값을 뽑아내는 로직 그리고 출력하는 로직이 모두 함께 있고 순수 텍스트만 출력할 수 있도록 설계 되었다. 즉 다음과 같은 요구 사항이 생겼다고 가정해보자.

    영수증을 HTML 태그로도 출력하는 함수를 추가 해주세요.

    이 책을 읽기 전 나였으면 statement 함수를 똑같이 복사해서 htmlStatement으로 명명하고 영수증을 출력하는 부분에서 출력하는 부분을 <p>총액</p>으로 수정하는 방식으로 했을 것이다. 하지만 이러한 방식은 청구서 작성 로직이 중복되어 있기 때문에 로직에 대한 변경사항이 생기면을 plain Text를 출력하는 함수, html 태그를 출력하는 함수 둘 다 수정 해야 된다.

    요구 사항이 변경 될 때마다 대대적인 수정을 해야되는 코드, 중복된 로직이 많은 코드... 바로 내가 작성하던 코드들이였다. 1장에선 이런 코드를 중복코드를 제거하고 요구사항에 유연하도록 간단한 리팩터링을 진행한다. 나는 이전에 작성하던 코드들을 요구사항 변경에 유연하고 로직이 중복되지 않게 구조를 변경하고 싶었기에 1장을 읽으면서 정말 공감되고 빨리 리펙토링을 진행하고 싶어졌다. 1장에서는 테스트 코드를 작성하지 않는다. 하지만 리팩터링하기 전에 제대로 된 테스트가 필요하다고 언급은 된다.

    1장 초반에는 앞서 봤들이 statement 함수의 문제점을 알게 됬고 리팩터링을 진행해야되는 이유를 알게 됬다. 그래서 그 후반 부에는 내내 리팩터링을 진행을 한다. 한 함수에 존재하는 많은 로직들을 하나하나 함수로 추출하고 작은 단계로 나눠 리팩토링을 진행한다.

    느낀점

    책에서 제시하는 리팩터링이 필요한 코드가 전형적인 내가 작성하는 코드였다. 그리고 요구사항이 변경 될 때마다 대대적으로 수정해야 되는 코드, 버그가 많이 발생하는 코드, 이러한 코드들을 개선하고 싶었다. 이 책은 나의 문제점과 고민을 해결 해주었다. 리팩터링 진행 과정을 보면서 정말 막혔던 머리가 뚫리는 기분이였다. 앞으로 다른 장들도 기대 된다.

    코드

    https://github.com/choejoonkyung/refactoring/tree/ch1

    반응형

    '코딩' 카테고리의 다른 글

    리팩터링 2판 리뷰 - 3장  (0) 2021.12.22
    리팩터링 2판 리뷰 - 2장  (0) 2021.12.22
    Javscript Iteration protocol  (0) 2021.11.21
    Javascript Promise  (0) 2021.11.21
    CSR과 SSR의 설명 및 장단점  (0) 2021.11.19