반응형
안녕하세요? 수구리입니다.
이번 포스팅에서는 Code Refactoring에 대한 내용에 대해서 알아보려고 합니다.
코드 리팩터링이란?
- 리팩터링은 사용하지 않는 코드 또는 중복된 코드를 지우고, 코드의 로직을 깨끗하고 이해하기 쉽게 디자인하는 것
- 이 개념은 Martin Fowler와 Kent Beck에 의해서 정의되었다고 한다.
- 이는 종종 최적화, 디버깅, 방어 코드 추가, 테스트하기 좋은 코드로 만드는 것과 혼동될 수 있다.
리팩터링의 목적
- 흔히 "리팩터링을 한다."라는 의미는 개발자의 실수를 만드는 것을 방지하는 것임에 유의하자
- 디자인에 작고 안전한 구조적 변화를 추가하는 것으로 리팩토링을 시작할 수 있는데 주의할 점은 항상 같은 동작, 기능을 수행해야 한다는 것이다.
- 리팩토링을 하면서 지속적으로 코드가 정상 동작을 하는지 확인해야 하고, 동작에 영향을 주어서는 안 된다.
리팩터링을 해야 하는 이유?
- 코드를 고치거나 바꾸는 것이 될 수도 있다.
- 이 과정은 코드를 쉽게 이해하고 유지보수에 좋게 하는 것에 초점이 맞춰져야 한다.
리팩터링과 클린 코드의 차이점?
- 가깝게 본다면 리팩터링과 클린 코드에 차이점이 별로 없어 보인다.
- 하지만 좀 더 멀리 떨어져서 본다면 리팩터링이 더 큰 의미를 가지는 것처럼 보인다.
- 클린 코드는 단순하게 가독성을 높이기 위한 작업이라면
- 리팩터링은 클린 코드를 포함하여 유지보수를 위한 코드의 개선이라고 볼 수 있다.
- 클린 코드와 같은 부분은 설계단계에서 잘 이루어져 있는 것이 중요하고, 리팩토링은 결과물이 나온 이후 수정이나 추가 작업이 진행될 때 개선해 나가도록 하자.
리팩터링의 과정
- 문제 찾기
- 어떤 부분에서 문제가 있는지?
- 무엇이 문제가 되는지?
- 문제 특징짓기
- 왜 어떤 것을 바꾸어야 하는지?
- 바꿈으로써 얻는 이점은 무엇인지?
- 바꿨을 때 위험한 점은 없는지?
- 솔루션 디자인하기
- 코드의 최종 목적은 무엇인지?
- 어떤 코드의 변환이 적당한 상태를 위해 움직일 코드인지?
- 코드 수정하기
- 코드 변환이 수행될 것의 코드 기능은 이전에 기능하던 것과 동일하게 되도록 남겨야 한다.
리팩터링 방법
- Rename 이름 재설정
- 메서드, 변수, 클래스 등등 이름을 덜 혼동하고 오해가 없도록 수정
- 개인적으로 클린 코딩 쪽에 더 가깝다고 봄.
- Move Class 클래스 이동
- 클래스를 더 잘 맞는 패키지로 이동시킨다.
- 모든 추가된 구문들은 주어진 클래스를 참조하는 게 좋다.
- 명확히 이해는 잘 안 가지만 아무튼 재사용과 관련되어서 클래스를 이동시키라는 의미인 것 같다.
- Extract Method 메서드 추출
- 긴 메서드를 쪼개서 가독성과 유지성을 높인다.
- 한 가지 일을 수행하는 코드의 부분을 서술적인 이름의 새로운 메서드로 만든다.
- 메소드 추출을 통해서 특정 기능을 재사용하도록 해준다.
- Extract Superclass 슈퍼클래스 추출
- 구체화시키는 클래스들 중에서 공통된 메서드는 정의를 위로 올린다.
- 서브 클래스에서 다양한 것들은 추상 메서드로 남겨둔다.
- 이는 효율적인 코드 재사용을 도와주고 새로운 서브클래스들이 만들고 사용되는 것을 허락해준다.
- Replace Conditional with Polymorphism 다형성을 조건으로 하는 것을 대체한다.
- if 나 switch 같은 의사결정 메서드를 만든다.
- 예를 들면, 너비와 타입에 의해 정의된 모양을 그리는 데에 사용되는 클래스가 있다. 하나는 중복을 방지하기 위해 다형성을 쓴다.
- 만약 클래스의 동작이 형태에 특정하다면, 코드를 단순화하기 위해서 서브클래스로 내릴 수 있다.
- 이것은 코드의 큰 변화 없이 다른 모양을 그리기 쉽게 만들어 준다.
리팩터링 예제
- 다음으로는 코드와 함께 리팩토링 과정을 따라가 보자.
직관적인 함수명과 변수명
// before
public int getFoodPrice(int a, int b){
return a * b;
}
// after
public int getTotalFoodPrice(int price, int quantiry){
return price * quantity;
}
메서드 추출
- (price * quantiry) 변수 추출
- 할인율 메소드 추출
- 할인율 메소드 pricate 선언
// before
public int getTotalPrice(int price, int quantiry, double discount) {
return (int) ((price * quantiry) * (price * quantiry) * (discount / 100));
}
// after
public int getTotalFoodPrice(int price, int quantiry, double discount) {
int totalPriceQuantity = price * quantiry;
return (int) (totalPriceQuantity - getDiscountPrice(discount, totalPriceQuantity));
}
private double getDiscountPrice(double discount, int totalPriceQuantity) {
return totalPriceQuantity * (discount / 100);
}
메소드 명 수정
- totalPriceQuantity를 getter 메서드로 추출하도록 변경
- 위의 after 코드에서 메소드 명 수정
// after
public int getTotalFoodPrice(int price, int quantiry, double discount) {
int totalPriceQuantity = getTotalPriceQuantity(price, quantiry);
return (int) (totalPriceQuantity - getDiscountPrice(discount, totalPriceQuantity));
}
private double getDiscountPrice(double discount, int totalPriceQuantity) {
return totalPriceQuantity * (discount / 100);
}
private int getTotalPriceQuantity(int price, int quantiry) {
return price * quantiry;
}
반응형
'🌈 프로그래밍' 카테고리의 다른 글
[ node/express ] 외부 API post 요청 시 json Array 객체를 포함해서 전송하기 (0) | 2022.11.18 |
---|---|
[ dbdiagram.io ] CLI 명령으로 DDL DB Diagram 쉽게 뽑기 (0) | 2022.06.09 |
[ Clean Code ] 클린 코딩을 하는 8가지 방법 (0) | 2021.11.10 |