리팩토링 2판을 읽고있다! 예시가 자바스크립트라 더 이해하기 쉽고, 유용할 것 같다.
기억하고 싶은 구절만 메모해 놔야지 :)
chapter 01. 리팩터링: 첫 번째 예시
1.2 예시 프로그램을 본 소감
- 나는 수백줄짜리 코드를 수정할 때면 먼저 프로그램의 작동 방식을 더 쉽게 파악할 수 있도록 코드를 여러함수와 프로그램 요소로 재구성한다. 구조가 빈약하다면 구조부터 바로잡은 뒤에 기능을 수정하는 편이 작업하기가 훨씬 수월하다.
(선: 리팩토링, 후: 기능추가)
- 잘 작동하고 나중에 변경할 일이 절대 없다면 코드를 현재 상태로 놔둬도 아무런 문제가 없다.
1.3 리팩터링이 첫 단계
- 먼저 테스트 코드부터 마련해야한다.
- 테스트를 작성하는 데 시간이 좀 걸리지만, 신경 써서 만들어두면 디버깅 시간이 줄어서 전체 작업 시간은 오히려 단축된다. (→ 4장)
(아무리 간단한 수정이라도 리팩터링 후에는 항상 테스트하는 습관!)
1.4 statement()함수 쪼개기
- 전체 동작을 각각의 부분으로 나눌 수 있는 지점을 찾는다. → switch
- (함수 반환값 - result라는 이름 사용)
- 컴퓨터가 이해하는 코드는 바보도 작성할 수 있다. 사람이 이해하도록 작성하는 프로그래머가 진정한 실력자다.
- 좋은 코드라면 하는 일이 명확히 드러나야 함 → 변수 이름 중요!
- 로컬변수 제거 → 추출 작업이 훨씬 쉬워진다는 장점
- 반복문이 깨져서 성능 느려진다? 미미함
만약 성능이 느려진다면, 리팩토링 후 성능개선하는 것이 효과적
따라서 특별한 경우가 아니면 무시하라
1.7 중간 점검: 두 파일(과 두 단계)로 분리됨
- 리팩토링후 44줄 짜리 코드 → 70줄 (함수로 추출하면서 함수 본문 열고 닫는 괄호가 덭붙여져서 그렇다)
- 추가된 코드 덕분에 전체 로직을 구성하는 요소 각각이 뚜렷이 부각되고, 계산하는 부분과 출력형식을 다루는 부분이 분리됐다. 이렇게 모듈화하면 각 부분이 하는 일과 그 부분이 맞물려 돌아가는 과정을 파악하기 쉬워진다.
- 간결함이 지혜의 정수일지 몰라도, 프로그래밍에서만큼은 명료함이 진화할 수 있는 소프트웨어 정수다.
- 항시 코드베이스를 작업 시작 전보다 건강하게(healthy) 만들어놓고 떠나야 한다.
1.8 다형성을 활용해 계산 코드 재구성하기
- 조건부로직을 다형성으로 바꾸기
- 생성자를 팩터리 함수로 바꾸기!
반복문 쪼개기, 문장 슬라이스하기, 함수 추출하기, 변수 인라인하기, 함수 옮기기, 조건부 로직을 다형성으로 바꾸기 등
[1장 리팩토링 단계]
- 원본함수를 중첩함수 여러 개로 나눈다
- 단계쪼개기 → 계신코드와 출력코드 분리
- 계산 로직을 다형성으로 표현
"좋은 코드를 가늠하는 확실한 방법은 '얼마나 수정하기 쉬운가'다"
Chapter 02: 리팩터링 원칙
2.1 리팩터링 정의
- 소프트웨어의 겉보기 동작은 그대로 유지한 채, 코드를 이해하고 수정하기 쉽도록 내부 구조를 변경하는 기법(함수 추출하기, 조건부 로직을 다형성으로 바꾸기)
- 특정한 방식에 따라 코드를 정리하는 것만이 리팩터링
- 누군가 "리팩터링하다가 코드가 깨져서 며칠이나 고생했다"라고 한다면, 십중팔구 리팩터링한 것이 아니다.
- 코드베이스를 정리하거나 구조를 바꾸는 모든 작업 ⇒ 재구성(restructuring), 리팩터링은 재구성 중 특수한 한 형태
2.2 두 개의 모자
- 소프트웨어를 개발할 때 목적이 '기능추가'냐 '리팩터링'이냐를 명확히 구분해 작업
2.3 리팩터링하는 이유
- 리팩터링하면 소프트웨어 설계가 좋아진다
- 아키텍처를 충분히 이해하지 못한 채 단기 목표만을 위해 코드를 수정하다 보면 기반 구조가 무너지기 쉽다 → 악효과 누적
- 중복 코드 제거 → 모든 코드가 언제나 고유한 일을 수행함 보장 - 바람직한 설계의 핵심
- 리팩터링하면 소프트웨어를 이해하기 쉬워진다
- 문제는 프로그램을 동작시키는 데만 신경 쓰다 보면 나중에 그 코드를 다룰 개발자를 배려하지 못한다는 데 있다.
- 단지 다른 사람을 배려하기 위해서가 아니다. 사실 그 다른 사람이 바로 나 자신일 때가 많다.
- 리팩터링하면 버그를 쉽게 찾을 수 있다
- 리팩터링하면 프로그래밍 속도를 높일 수 있다
- 리팩터링하면 기존 코드의 설계를 얼마든지 개선할 수 있으므로, 설령 프로그램의 요구사항이 바뀌더라도 설계를 지속해서 개선할 수 있다. 처음부터 좋은 설계 - 어려움 → 리팩터링하자
2.4 언제 리팩터링해야 할까?
[3의 법칙]
1. 그냥한다
2. 비슷한 일을 두번째로 하게되면, 일단 계속 진행한다.
3. 비슷한 일을 세번째 하게 되면 리팩터링한다.
- 준비를 위한 리팩터링: 기능을 쉽게 추가하기 만들기
- 다들 "직진!"을 외치더라도, 때로는 "잠깐, 지도를 보고 가장 빠른 경로를 찾아보자"고 말할 줄 알아야 한다. 준비를 위한 리팩터링이 바로 이런 역할을 한다.
- 이해를 위한 리팩터링: 코드를 이해하기 쉽게 만들기
- 리팩터링하면 머리로 이해한 것을 코드에 옮겨 담을 수 있다. 그런 다음 수정한 코드를 테스트해보면 내 생각이 맞았는지 확인할 수 있다. 내가 이해한 것을 코드에 반영해두면 더 오래 보존할 수 있을 뿐만 아니라 동료들도 알 수 있다.
- 쓰레기 줍기 리팩터링
- 계획된 리팩터링과 수시로 하는 리팩터링
- 보기 싫은 코드를 발견하면 리팩터링하자. 그런데 잘 작성된 코드 역시 수많은 리팩터링을 거쳐야 한다.
- 뛰어난 개발자는 새 기능을 추가하기 쉽도록 코드를 '수정'하는 것이 그 기능을 가장 빠르게 추가하는 길일 수 있음을 안다.
- 오래 걸리는 리팩터링
- 예컨대 라이브러리를 교체할 때는 기존 것과 새 것 모두를 포용하는 추상 인터페이스부터 마련한다. 기존 코드가 이 추상 인터페이스를 호출하도록 만들고 나면 라이브러리를 훨씬 쉽게 교체할 수 있다. (추상화로 갈아타기 전략)
- 코드 리뷰에 리팩터링 활용하기
- 관리자에게는 뭐라고 말해야 할까?
- 말하지 않는다 😂 (구체적인 방법은 개발자가 판단하는 것. 가장 빠르게 구현하는 방법은 리팩터링)
- 리팩터링하지 말아야 할때
- 내부 동작을 이해해야할 시점에 리팩터링해야 효과를 제대로 볼 수 있다.
- 리팩터링하는 것보다 처음부터 새로 작성하는 게 쉬울 때도 리팩터링하지 않는다.
2.5 리팩터링 시 고려할 문제
- 새 기능 개발 속도 저하
- 코드 소유권
- 브랜치
- 테스팅
- 래거시코드
- 데이터베이스
2.6 리팩터링, 아키텍처, 애그니(YAGNI)
- 코딩 전에 아키텍처를 확정지으려 할 때의 대표적인 문제는 소프트웨어 요구사항을 사전에 모두 파악해야 한다는 것이다. 하지만 막상 해보면 실현할 수 없는 목표일 때가 많다.
- 리팩터링을 활용하면, 앞으로 어느 부분에 유연성이 필요하고 어떻게 해야 그 변화에 가장 잘 대응할 수 있을지 추측하지 않고, 그저 현재까지 파악한 요구사항만을 해결하는 소프트웨어를 구축한다.
- YAGNI: you aren't going to need it (필요 없을 거다)
2.7 리팩터링과 소프트웨어 개발 프로세스
- 자가 테스트 코드 + 리팩터링 ⇒ 테스트 주도 개발(TDD)