[스터디] 리팩터링_chapter 3_언제 리팩터링을 해야 하는가

김하은·2024년 5월 9일
1

스터디

목록 보기
19/23

3장에서는 리팩터링을 언제 적용해야 하는지를 판단하는 기준을 제시한다. 책에서는 리팩터링할 '시점'을 설명할 때 '냄새'라는 표현을 사용했다. 쓰레기를 제때 치우지 않으면 악취가 나고 문제를 일으키기 마련인데 정리되지 않은 코드도 문제를 일으킬 수 있고 찜찜함을 남긴다는 점에서 매우 재밌고 정확한 표현이라고 생각했다.

3장에서는 코드가 풍기는 냄새의 종류를 소개하고 있는데, 이 장에서 배운 내용을 기반으로 내 코드에서 나타난 문제점에도 이름을 붙일 수 있을 것 같다. 문제에 이름을 붙이면 해결이 더 쉬워지므로 꼼꼼히 이해하고 내가 그동안 짠 코드들에 대입해보려고 노력했다. 물론 이해가 안되는 부분도 있었는데, 앞으로 책을 더 읽으면서 이해되리라고 생각하고 일단은 넘어갔다. 이해한 개념들을 중심으로 책 내용을 정리해 보았다.

기이한 이름

  • 아래 인용 부분이 특히 와닿았다. 코드를 짜다가 함수나 변수명이 바로 떠오르지 않는 경우는 내가 그 코드 구조를 모호하게 파악하고 있거나 코드 구조가 잘못된 경우가 많았다.

    이름 바꾸기는 단순히 이름을 다르게 표현하는 연습이 아니다. 마땅한 이름이 떠오르지 않는다면 설계에 더 근본적인 문제가 숨어 있을 가능성이 높다.

중복 코드

  • 아래 인용 문장을 이해하기 어려워서 코드로 나타내 보았다.

    한 클래스에 딸린 두 메서드가 똑같은 표현식을 사용하는 경우가 있다.

    • calculateArea() 메서드와 calculateVolume() 메서드 모두 length * width 라는 동일한 표현식을 사용하고 있는데. 이것이 중복 코드의 가장 기본적인 형태이다.
      const myObject = {
      calculateArea(length, width) {
        return length * width;
      },
      calculateVolume(length, width, height) {
        return length * width * height;
      }
      };
      	```
    • 이런 경우 함수 추출 기법을 사용하여 중복 코드를 제거할 수 있다.
      const myObject = {
      calculateRectangleArea(length, width) {
        return length * width;
      },
      calculateArea(length, width) {
        return this.calculateRectangleArea(length, width);
      },
      calculateVolume(length, width, height) {
        return this.calculateRectangleArea(length, width) * height;
      }
      };
      	```
        

긴 함수

  • 긴 코드를 짧게 구성할 때 코드를 읽는 사람 입장에서 함수가 하는 일을 파악하기 위해 왔다 갔다 해야 하므로 여전히 부담이 되지 않을까 하는 우려를 한적이 있다. 책에서는 이에 대해 이렇게 이야기 한다.

    짧은 함수로 구성된 코드를 이해하기 쉽게 만드는 가장 확실한 방법은 좋은 이름이다. 함수 이름을 잘 지어두면 본문 코드를 볼 이유가 사라진다.

  • 긴 함수를 쪼갤 때 기준을 어떻게 삼아야 할지 고민한 적이 있다. 책에서는 이렇게 정의 해 준다.

    • 여기서 핵심은 함수의 길이가 아닌, 함수의 목적 (의도)과 구현 코드의 괴리가 얼마나 큰가다. 즉, '무엇을 하는지'를 코드가 잘 설명해주지 못할수록 함수로 만드는 게 유리하다.
    • 코드가 단 한 줄이어도 따로 설명할 필요가 있다면 함수로 추출하는 게 좋다.

긴 매개변수 목록

  • 코드를 짜다보면 (특히 api 관련 함수에서) 매개변수 목록이 길어질 때가 있었고, 이럴때 마다 난감했다. 책에서는 다음과 같은 방법을 추천했다.
    • 매개변수를 질의 함수로 바꾸기, 객체 통째로 넘기기, 매개변수 객체 만들기, 플래그 인수 제거하기, 여러 함수를 클래스로 묶기
    • 이 기법들에 대해서는 6장과 11장에서 더 자세히 배울 것이다. 기대된다.

전역 데이터

  • 전역 데이터는 어디서든 변경할 수 있지만 그 원인이 되는 코드를 찾아내기 어렵게 하기 때문에 문제가 될 수 있는데 변수 캡슐화하기를 통해 리팩터링 할 수 있다.
  • 사실 캡슐화에 대한 정확한 개념을 잘 모른다. 그래서 이 강의를 들어보려 한다.
    코드잇 캡슐화 강의

뒤엉킨 변경 & 산탄총 수술

코드를 수정할 때는 시스템에서 고쳐야 할 딱 한 군데를 찾아서 그부분만 수정할 수 있기를 바란다. 이렇게 할 수 없다면 뒤엉킨 변경과 산탄총 수술 중 하나가 풍긴다.

뒤엉킨 변경은 단일 책임 원칙(Single Responsibility Principle)이 제대로 지켜지지 않을 떄 나타난다.

  • SPR: 위키피디아에 따르면 단일 책임 원칙이란 "A module should be responsible to one, and only one, actor."라고 설명 돼 있는데 "하나의 모듈은 반드시 하나의 동작만의 책임을 갖는다"는 원칙이다.

산탄총 수술은 뒤엉킨 변경과 비슷하면서도 정반대다. 이 냄새는 코드를 변경할 때마다 자잘하게 수정해야 하는 클래스가 많을 때 풍긴다.

  • 즉, 뒤엉킨 변경은 하나의 클래스나 모듈이 너무 많은 변화를 겪는 상황이며, 산탄총 수술은 하나의 변경이 여러 클래스를 동시에 수정해야 하는 상황을 이야기 한다.
profile
아이디어와 구현을 좋아합니다!

0개의 댓글