재 현
파이브 라인스 오브 코드 읽기(1) 본문
우선, 책의 제목처럼 "다섯 줄로 만들기 위한 기본 패턴"을 예로 들기 전에, 리팩토링이란 뭔지부터 보자.
리팩토링이란?
"그거 머 코드 재사용하게 하는 거 아냐?" "좀 빠르게 만드는 거 아냐?"
이것도 맞는 말이다. 하지만 가장 핵심적인 이유가 있다.
좋은 코드란, "사람이 읽기 쉽고, 유지보수가 용이하며, 의도한 대로 잘 동작한 코드이다."
그런 의미에서 리팩토링이란 " 기능을 변경하지 않고, 코드의 가독성과 유지보수가 쉽도록 코드를 변경하는 것"이라고 할 수 있겠다.
코드를 읽는 시간이 작성하는 시간보다 많다.
대부분의 프로그래머들은 코드를 읽고 이해하는데 많은 시간을 할애한다. 이해하지 못하고 변경하면 치명적인 장애를 발생시킬 수 있기 때문이다. 그리고 우리 프로그래머들의 시간은 비싸다. 코드베이스의 가독성을 높이면 새로운 기능을 구현하는 시간을 확보할 수 있다.
그럼 리팩토링 언제 해??
일반적으로, 탐색 -> 명세화 -> 구현 -> 테스트 -> 리팩토링 -> 전달 단계에서 하면 된다. 요구사항을 분석(탐색)하고, 명세화하고, 코드를 구현하고, 명세사항을 따르는지 확인하고, 리팩토링하고, 풀리퀘스트를 통해 전달한다.
그럼 리팩토링 뭘 해야 돼??
질문이 생긴다. 좋은 건 알겠는데 뭐 고치라고?? 예를 들어보자, SRP(단일 책임 원칙) 즉 하나만 해. 우리는 이놈이 뭔지 잘 알고 있다. 함수나 메서드나 하나의 기능을 하는 것이 좋은 것을 안다. SRP에 대해 코드 스멜(코드가 나쁘다는 것을 암시) 능력을 가지고 있단 소리다. 그렇다면 다음의 예를 보자.
이 함수는 SRP 위반일까? 아닐까?
함수 내에서 나누고, 거듭제곱한 다음, 다시 곱한다. 그렇다면 이건 세가지의 일을 하는 것일까? 1개의 숫자만 반환하고 상태가 바뀌지 않기 때문에 한 가지 작업만 수행하는 걸까?
이를 위해 책에서 말해주는 규칙들을 살펴보자.
첫 번째 규칙: 다섯 줄 제한
- 규칙: 메서드는 {와 }를 제외하고 5줄 이상이 되어서는 안 된다.
- 설명: 문장이라고도 하는 코드 한 줄은 하나의 if, for, while 또는 세미콜론으로 끝나는 것을 말한다. (공백과 중괄호 제외)
어떤 메서드도 5줄 이상 가질 수 없다는 간단한 규칙이다. 5줄 코드를 가진 4개의 메서드가 20줄인 하나의 메서드 보다 훨씬 이해하기 쉽다. 우리는 이 규칙을 위해 메소드 추출을 할 수 있다.
메서드 추출은 다음과 같다.
- 구분되는 작업을 수행하는 코드 블록을 메서드로 분리
- 긴 메소드 → 다른 메서드를 호출하는 짧은 메서드로 변경
- 이름을 가지면서, 맥락에 따른 의도/의미 표현 가능
예를 들어보자.
위와 같은 코드가 있고, indent도 3일 뿐더러 다섯 줄을 넘어간다. 우리는 저 if문을 리팩토링 하고자 한다. 그럼 다음과 같은 절차가 수행될 것이다.
- 새로운 min 메서드를 생성한다.
- 리팩토링 할 라인에 min 메서드를 호출한다.
- 매개변수를 추가한다.
- 추출된 함수의 결과를 result에 할당한다.
- 컴파일한다.
그럼 다음과 같은 코드가 만들어진다.
다섯 줄 규칙도 완성되면서 확실히 깔끔해졌다. 읽기도 쉬워졌다. 그리고 확실히 아무것도 손상시키지 않았다. 이 말을 갑자기 왜? 하면 다시 리팩토링의 정의를 다시 읽고 와보자. 처음에 "기능을 변경하지 않고"가 있다. 우리가 아무것도 고장 내지 않았다는 확신이, 완벽한 결과보다 더 가치 있다.
두 번째 규칙: 단일 책임을 위한 두 규칙
- 규칙 1: 호출 또는 전달, 한 가지만 할 것
위 코드를 보자. g는 메서드를 호출하기도 하고, 다른 메서드의 인자로 전달되기도 한다. 우리는 호출 또는 전달, 한 가지만 하도록 고칠 수 있다.
createGraphics 함수를 만들어 g를 반환시켰다. 그랬더니 g는 인자의 역할만 하도록 되었다. draw 메서드를 읽을 때 이제 g가 어떤 변수인지 확실하게 알게 됐다.
- 규칙 2: if문은 함수의 시작에만 배치
소수를 출력하는 함수다. 우리는 이제 함수는 한 가지의 일만 해야 된 다는 걸 안다. 그런데 무언가를 확인하는 것도 한 가지 일이다. 따라서 함수에 if가 있는 경우 함수의 첫 번째 항목이어야 한다. 그 후에 아무것도 해서는 안된다. 규칙을 적용하면 다음과 같다.
무언가를 확인하는 건 하나의 작업이기 때문에, 하나의 함수에서 처리해야 한다. 이 규칙은 if문이 하나의 작업이기 때문에 분리할 때 이어지는 else if는 if문과 분리할 수 없는 원자 단위로 본다. 즉, if문 메서드 빼려면 else if도 같이 빼야 된다.
그렇다면 여기서 질문해보자.
우리는 왼쪽을 규칙에 의해 오른쪽으로 수정했다. 그렇게 if문은 함수의 시작에만 배치했다. 그랬더니 다섯 줄 제한 규칙을 지키기 어렵다. 왜냐면 if와 else if는 세트이기 때문에... 그러면 어떻게 해결할 수 있을까?
이에 대한 해결 책으로 새로운 규칙을 소개한다. (다음 글)
출처:
'Development' 카테고리의 다른 글
JUnit 4와 JUnit 5에서 제공하는 Assertions(번역) (1) | 2023.11.01 |
---|---|
객체지향 생활체조 9가지 원칙 (1) | 2023.11.01 |
주식 자동 매수/매도 프로그램 만들기 후기 (0) | 2023.08.02 |
우아한 객체 지향 - 의존성 (0) | 2023.08.02 |
const의 위력 (0) | 2023.07.31 |