[리팩터링] 1장 리팩터링 리팩터링하기

공효은·2023년 5월 1일
0

refactoring

목록 보기
1/12
post-custom-banner

오늘 5월1일 Five Lines of Code 나홀로 스터디 첫날이다.
앞으로 한달동안 매일 야금야금 책 파먹기! 홧팅

이 장의 주요 내용

  • 리팩터링 구성요소 이해
  • 일상 업무에 리팩터링 도입
  • 리팩터링에 있어 안전의 중요성
  • 1부의 핵심 예제

1.1 리팩터링이란 무엇인가.

가장 단순한 형태의 리팩터링은 '기능을 변경하지 않고 코드를 변경하는 것'을 의미한다.

예시

// 변경 전
return pow(base, exp / 2) * pow(base, exp / 2);

//변경후
let result = pow(base, exp / 2);![](https://velog.velcdn.com/images/he0_077/post/cddf30a2-09fd-42dc-b9b9-ed43745a7636/image.png)

return result * result;

리팩터링을 해야하는 이유는 여러 가지가 있다.

  • 코드를 더 빠르게 만들기 위해(앞의 예시)
  • 더 작은 코드를 만들기 위해
  • 코드를 더 일반적이거나 재사용 가능하게 하기 위해
  • 코드의 가독성을 높이고 유지보수를 용이하게 하기 위해

정의
좋은 코드(Good code) - 사람이 읽기 쉽고, 유지보수가 용이하며, 의도한 대로 잘 동작하는 코드

정의
리팩터링(refactoring) - 기능을 변경하지 않고 코드의 가독성과 유지보수가 쉽도록 코드를 변경하는 것

대부분의 프로그래머는 코드를 작성하는 것 보다 코드를 읽고 이해하는 데 더 많은 시간을 보낸다. 복잡한 분야에서 작업하기 때문에 이해하지 못하고 뭔가를 변경하면 치명적인 장애가 발생할 수 있기 때문이다.

리팩터링의 첫 번째 이유: 경제적임. 프로그래머의 시간은 비싸기 때문에 코드베이스의 가독성을 높이면 새로운 기능을 구현하기 위한 시간을 확보할 수 있다.

리팩터링의 두 번째 이유: 유지보수가 용이해지면 버그가 줄어들고 수정이 쉬워진다.

리팩터링의 세 번째 이유: 좋은 코드베이스는 생각하기 편하다.

1.2 스킬: 무엇을 리팩터링할 것인가?

코드 스멜은 코드가 나쁘다는 것을 암시하는 것이다. 강력하지만, 추상적이고 시작하기도 어려우며 보는 감각을 키우는 데 시간이 걸린다.

1.2.1 코드 스멜의 예

잘 알려진 코드 스멜은 다음과 같다. '함수는 한 가지 작업을 수행해야 한다.' 이것은 풀륭한 지침이지만 한 가지가 무엇인지 알기란 쉽지 않다. 이전의 코드를 다시 살펴보면 스멜이 존재하는가? 나누고 거듭제곱한 다음 곱하기를 한다. 이것은 세 가지 일을 한다는 의미일까? 그렇지 않으면 1개의 숫자만 반환하고 상태가 변하지 않기 때문에 한 가지 작업만 수행하는 것일까?

1.3 문화: 리팩터링은 언제 할까?

"리팩터링은 샤워하는 것과 같습니다."

리팩터링은 정기적으로 수행하는 것이 효과적이고 비용이 적게 들기 때문에 가능하면 일상 업무에 통합하는 것이 좋다.
프로그래밍 작업으로 문제를 해결 할 때 사용하는 6단계 작업 절차를 권장한다.

  1. 탐색(Explore): 처음부터 무엇을 만들어야 할지 확신이 서지 않는 경우가 많다. 고객이 자신이 원하는 것을 모르는 경우도 있고 요건이 모호한 글로 기재되어 있는 경우도 있다. 또 문제를 해결할 수 있을지 조차 모르는 경우도 있다.
    그러므로 항상 실험부터 시작해야한다. 무엇인가를 신속하게 구현하면 고객이 무엇을 필요로 하는지 함께 확인 할 수 있다.

  2. 명세화(Specify): 무엇을 만들지 알게 되면 그것을 명세화 한다. 최적의 경우, 이것은 자동화된 테스트의 형태가 된다.

  3. 구현(Implement): 코드를 구현한다.

  4. 테스트(Test): 코드가 2단계의 명세(사양)를 따르는지를 확인한다.

  5. 리팩터링(Refactor): 코드를 전달하기 전에 다음 사람이 쉽게 작업할 수 있는지 확인한다.(다음사람이 우리가 될 수도 있음..ㅋㅋ)

  6. 전달(Deliver): 전달하는 방법에는 여러 가지가 있는데, 가장 일반적인 것은 풀리퀘스트(pull request)또는 특정 브랜치(branch)로 푸시(push)하는 것이다.

1.3.1 레거시 시스템에서의 리팩터링

대규모 레거시 시스템에서 리팩터링을 시작할 때 모든 것을 중단한 후 코드베이스 전체를 먼저 리팩터링할 필요 없이 일상 업무에 결합할 수 있는 좋은 방법이 있다. 그저 다음의 멋진 인용구를 따르면 된다.

"우선 변경하기 쉽게 만든 후 변경하라."

새로운 것을 구현할 대마다 새 코드를 쉽게 추가 할 수 있게 리팩터링을 먼저 한다. 이것은 요리를 시작하기 전에 필요한 재료를 준비하는 것과 유사하다.

1.3.2 언제 리팩터링을 하지 말아야할까?

  • 한 번 실행하고 삭제할 코드. 이것은 익스트림 프로그래밍 커뮤니티에서 스파이크로 알려진 것이다.
  • 폐기 되기 전 유지보스 모드에 있는 코드
  • 임베디드 시스템이나 게임의 고급 물리엔진과 같이 엄격한 성능 요구사항이 있는 코드

그 밖에 모든 경우에는 리팩터링에 투자하는 것이 좋다!

1.4 도구: (안전한) 리팩터링 방법

소프트웨어 개발에서 자동화된 테스트는 자동차의 브레이크와 같다. 자동차가 느리게 갈 때는 브레이크가 존재감이 없지만 빨리 달릴 때는 브레이크가 있어 안전하다고 느낀다. 소프트웨어도 마찬가지다. 자동화된 테스트를 수행하면 안심하고 빠르게 진행할 수 있다. 이 책에서는 완전히 새로운 스킬을 배우기 때문에 빨리갈필요 없음(테스트를 따로 다루지 않음)

다음과 같은 도구에 많이 의존하는게 좋다.

  • 레시피처럼 상세하고 단계별로 구조화된 리팩터링 패턴
  • 버전 관리(Git)
  • 컴파일러

1.5 시작하는 데 필요한 도구

코딩과 리팩터링은 모두 손가락으로 수행하는 스킬이다. 따라서 가장 좋은 학습은 손가락으로 예제를 따라하고, 실험하고, 손으로 반복하는것을 즐기는 것이다!

1.5.1 프로그래밍 언어: 타입스크립트

  • 자바, C#, C++, 자바스크립트 처럼 일반적으로 사용되는 프로그래밍 언어와 모양과 느낌이 비슷함.
  • 타입스크립트는 완전한 '비객체지향' 코드 (즉, 클래스가 전무한 코드) 에서 고도의 '객체지향' 코드로 전환하는 방법을 제공함

1.5.2 편집기: 비주얼 스튜디오 코드

  • 타입 스크립트와 잘 맞음
  • 컴파일 수행을 지우너하도록 백그라운드 터미널에서 tsx -w 명령 실행을 지원하기 떄문에 손수 컴파일하지 않아도 됨

1.5.3 버전관리: Git

참조하는 예제 코드의 재설정

다음 명령어로 주요 절의 시작부분을 살펴봐야할 때 언제든지 해당 코드로 이동할 수 있음

git reset --hard section-2.1
주의: 변경 내용이 모두 소실됨

1.6 핵심 예제: 2D 퍼즐 게임

책의 1부에서 하나의 코드베이스를 사용한다. 하나의 예제를 사용하면 모든 장에서 새로운 예제에 익숙해질 필요가 없기 때문에 시간을 아낄 수 있다.

예제는 사용게임에서 사용되는 것과 유사하게 사실적인 스타일로 작성되어 있다.
이 코드는 이미 DRY(Don't Repeat Yourself), KISS(Keep It Simple, Stupid) 원칙을 준수하고 있지만 완전하지 않다~

1.7 실제 환경에서 소프트웨어에 대한 주의사항

이 책의 핵심은 리팩터링에 대한 소개이고 모든 상황의 프로덕션 코드에 적용할 수 있는 특별한 규칙을 제공하는게 아니다.
규칙을 사용하는 방법은 먼저 그 이름을 익히고 따라하는 것이다. 여기에 익숙해지면 예외를 포함한 설명을 학습한다. 마지막으로 이 설명을 사용해서 코드 스멜에 대한 기본적인 이해를 쌓는다.

요약

  • 리팩터링을 수행하려면 리팩터링 대상을 식별하는 스킬과 리팩터링 단계를 명시적으로 가진 문화, 리팩터링을 돕는 도구의 조합
  • 일반적으로 코드 스멜은 리팩터링 대상을 설명하는 데 사용된다. 이것들은 모호해서 주니어 프로그래머가 내면화하기 어렵다. 이 책에서는 학습하는 동안 코드 스멜을 대체할 구체적인 규칙을 제공한다. 규칙에는 세 가지 추상화 수준이 있다. 매우 구체적인 이름, 예외 형태로 뉘앙스를 더하는 설명, 마지막으로 그것들이 나오게 된 스멜의 의도이다.
  • 자동화된 테스트와 리팩터링을 별도로 학습하면 진입 장벽을 낮출 수 있다. 자동화된 테스트 대신 컴파일러, 버전 관리 및 수동 테스트를 사용한다.
  • 리팩터링의 작업 절차는 레드-그린-리팩터 반복에서 테스트 주도 개발로 연결된다. 이는 자동화된 테스트에 의존한다는 것을 의미한다. 그래서 이를 대신해 새로운 코드를 만들 때 사용하는 6단계의 작업 절차(탐색, 명세화, 구현, 테스트, 리팩터링 전달)를 사용하거나 코드를 변경하기 직전에 리팩터링을 수행하도록 권장한다.
  • 이 책의 1부에서는 비주얼 스튜디오 코드, 타입스크립트, Git을 사용해 2D 퍼즐 게임의 소스코드를 바꾼다.
profile
잼나게 코딩하면서 살고 싶어요 ^O^/
post-custom-banner

0개의 댓글