초고교급 희망

리팩터링 Chapter 01~03 본문

Book

리팩터링 Chapter 01~03

연모링 2023. 8. 6. 11:42
728x90

Chapter 01

리팩터링이란?

겉으로 드러나는 코드의 기능(겉보기 동작)은 바꾸지 않으면서 내부 구조를 개선하는 방식으로 소프트웨어 시스템을 수정하는 과정이다.

예시 프로그램에서 발견한 수정할 부분

프로그램이 새로운 기능을 추가하기에 편한 구조가 아니라면, 먼저 기능을 추가하기 쉬운 형태로 리팩터링 하고나서 원하는 기능을 추가한다.

1)HTML로 출력하는 기능을 위한 복사본

로직을 변경할 일이 절대 없다면 상관없지만, 오래 사용할 프로그램이라면 중복 코드는 골칫거리가 된다.

2)연극 장르와 공연료 정책이 달라지는 변경사항

리팩터링이 필요한 이유는 바로 변경 때문이다. 다른 사람이 읽고 이해해야 할 일이 생겼는데로직을 파악하기 어렵다면 대책을 마련해야 한다.

디지털 시대의 연약한 자여, 그대 이름은 소프트웨어’

조금씩 변경하고 매번 테스트하는 것은 리팩터링 절차의 핵심이다.

리팩터링은 프로그램 수정을 작은 단계로 나눠 진행한다. 그래서 중간에 실수하더라도 버그를 쉽게 찾을 수 있다.

저자는 함수의 반환 값에는 항상 result라는 이름을 쓴다. 그러면 그 변수의 역할을 쉽게 알 수 있다.

또한 자바스크립트와 같은 동적 타입 언어를 사용할 때는 타입이 드러나게 작성하면 도움이 된다. 매개변수 이름에 접두어로 타입 이름을 적는데, 매개변수의 역할이 뚜렷하지 않을 때는 부정관사(a/an)를 붙인다.

컴퓨터가 이해하는 코드는 바보도 작성할 수 있다. 사람이 이해하도록 작성하는 프로그래머가 진정한 실력자다.

지역 변수를 제거해서 얻는 가장 큰 장점은 추출 작업이 훨씬 쉬워진다는 것이다. 유효범위를 신경 써야 할 대상이 줄어들기 때문이다.

반복문이 중복되는 것을 꺼리는 이들이 많지만, 사소한 중복은 성능에 미치는 영향이 미미할 때가 많다.

리팩터링으로 인한 성능 문제에 대한 저자의 조언은 ‘특별한 경우가 아니라면 일단 무시하라’라는 것이다.

변수 제거하기 작업의 단계를 잘게 나눈 예시

  1. 반복문 쪼개기
  2. 문장 슬라이드하기
  3. 함수 추출하기
  4. 변수 인라인 하기

상황이 복잡해지면 단계를 더 작게 나누는 일을 가장 먼저 하라. 테스트에 실패했을 때 최근 커밋으로 돌아가 리팩터링의 단계를 더 작게 나누어 다시 시도할 수 있다. 또한 코드가 복잡할 수록 단계를 작게 나누면 작업 속도가 빨라지기 때문이다.

느낀 점: 꼭 코드 리팩터링이 아니더라도 인생의 모든 목표들은 잘게 나눌수록 달성하기 쉬운 것 같다고 생각하는데 다른 분들은 어떠신가요?

공연 정보 레코드에 연극 데이터를 추가할 때 공연 객체를 복사했다. 그 이유는 가변 데이터는 금방 상하기 때문에 데이터를 최대한 불변처럼 취급하는 것이 좋다.

모듈화

계산하는 부분과 출력 형식을 다루는 부분을 분리했다.

이렇게 모듈화하면 각 부분이 하는 일과 그 부분들이 맞물려 돌아가는 과정을 파악하기 쉬워진다.

간결함이 지혜의 정수일지 몰라도, 프로그래밍에서만큼은 명료함이 진화할 수 있는 소프트웨어의 정수다.

캠핑자들에게는 “도착했을 때보다 깔끔하게 정돈하고 떠난다”는 규칙이 있다. 프로그래밍도 마찬가지다. 항시 코드베이스를 작업 시작 전보다 건강하게 만들어놓고 떠나야 한다.

‘컴파일-테스트-커밋’ 잊지말고 기회가 될 때마다 실행해야 한다.

다형성을 활용해 계산 코드 재구성하기

일반적인 경우를 기본으로 삼아 슈퍼클래스에 남겨두고, 장르마다 달라지는 부분은 필요할 때 오버라이드하게 만드는 것이 좋다.

서브클래스를 언제 사용하면 좋을까?

같은 타입의 다형성을 기반으로 실행되는 함수가 많을수록.

좋은 코드를 가늠하는 확실한 방법은 ‘얼마나 수정하기 쉬운가’다.

 

Chapter 02

두 개의 모자

항상 내가 쓰고 있는 모자가 무엇인지와 그에 따른 미묘한 작업 방식의 차이를 분명하게 인식해야 한다.

저자는 소프트웨어를 개발할 때 목적이 ‘기능 추가’냐, 아니면 ‘리팩터링’이냐를 명확히 구분해 작업한다.

본인이 하고자 하는 일의 방향성을 확실하게 하고, 그에 적합한 작업만 하라는 뜻이다.

리팩터링하는 이유

  1. 소프트웨어 설계가 좋아진다.
  2. 소프트웨어를 이해하기 쉬워진다.
  3. 버그를 쉽게 찾을 수 있다.
  4. 프로그래밍 속도를 높일 수 있다.

언제 리팩터링해야 할까?

3의 법칙

  1. 처음에는 그냥 한다.
  2. 비슷한 일을 두 번째로 하게 되면, 일단 계속 진행한다.
  3. 비슷한 일을 세 번째 하게 되면 리팩터링한다.

스트라이크 세 번이면 리팩터링하라(삼진 리팩터링)

리팩터링 작업 대부분은 드러나지 않게, 기회가 될 때마다 해야 한다.

원하는 방향으로 조금씩 개선하는 식이다.

리팩터링하지 말아야 할 때

내부 동작을 이해해야 할 시점에 리팩터링해야 효과를 제대로 볼 수 있다.

리팩터링하는 것보다 처음부터 새로 작성하는 게 쉬울 때도 하지 않는다.

리팩터링의 궁극적인 목적은 개발 속도를 높여서, 더 적은 노력으로 더 많은 가치를 창출하는 것이다.

리팩터링하도록 이끄는 동력은 어디까지나 경제적인 효과에 있다.

코드 소유권

저자가 선호하는 방식은 코드의 소유권을 팀에 두는 것이다.

그래서 팀원이라면 누구나 팀이 소유한 코드를 수정할 수 있게 한다.

오픈 소스 모델

: 다른 팀 사람이 자기 팀 코드의 브랜치를 따서 수정하고 커밋을 요청하는, 흡사 오픈소스 개발 모델.

변경 사항 커밋을 클라이언트를 관리하는 쪽에서 승인하면 기존 함수를 삭제할 수 있다.

브랜치

기능별 브랜치의 통합 주기를 2~3일 단위로 짧게 관리해야 한다.

레거시 코드

프로그램에서 테스트를 추가할 틈새를 찾아서 시스템을 테스트해야 한다.

데이터베이스

병렬 수정으로 필드 이름을 바꾸는 예시

  1. 첫 번째 커밋에서는 새로운 데이터베이스 필드를 추가만 하고 사용하지는 않는다.
  2. 기존 필드와 새 필드를 동시에 업데이트하도록 설정
  3. 데이터베이스를 읽는 클라이언트들을 새 필드를 사용하는 버전으로 조금씩 교체
  4. 더는 필요가 없어진 예전 필드를 삭제

애그니(YAGNI)

앞으로 어느 부분에 유연성이 필요하고 어떻게 해야 그 변화에 가장 잘 대응할 수 있을지 추측하지 않고, 그저 현재까지 파악한 요구사항만을 해결하는 소프트웨어를 구축한다.

호출하는 측에서 항상 같은 값을 넘기는 매개변수는 매개변수 목록에 넣지 않는다.

리팩터링과 성능

성능을 개선하기 위한 최적화가 프로그램의 특정 동작에만 관련될 뿐, 정작 컴파일러와 런타임과 하드웨어의 동작을 제대로 이해하지 못한 채 작성할 때도 많다.

시스템에 대해 잘 알더라도 섣불리 추측하지 말고 성능을 측정해봐야 한다.

프로파일러로 프로그램을 분석하여 시간과 공간을 많이 잡아먹는 지점을 알아낸다. 그리고 성능에 큰 영향을 주는 부분만 집중해서 최적화한다.

 

Chapter 03

긴 함수

함수 본문에는 원래 주석으로 설명하려던 코드가 담기고, 함수 이름은 동작 방식이 아닌 ‘의도’가 드러나게 짓는다.

‘무엇을 하는지’를 코드가 잘 설명해주지 못할수록 함수로 만드는 게 유리하다.

전역 데이터

데이터를 함수로 감싸는 것만으로도 데이터를 수정하는 부분을 쉽게 찾을 수 있고 접근을 통제할 수 있게 된다.

반복되는 switch문

똑같은 조건부 로직이 여러 곳에서 반복해 등장하는 코드에 집중하자.

주석을 남겨야겠다는 생각이 들면, 가장 먼저 주석이 필요 없는 코드로 리팩터링해본다.

 

728x90

'Book' 카테고리의 다른 글

[게임 프로그래밍 패턴] 2장 명령 패턴  (0) 2023.07.17