코딩할 때 가볍게 다루기 좋은 리팩토링에 대해 소개하려고 한다. 😀
코드의 이해를 높이는 데 도움이 되며 사실상 어떠한 비용도 들지 않으니 신경 써주는 게 좋다. 👍
사소하지만 코딩하는 과정에 도움이 되었으면 한다. 필자도 프로젝트하면서 한 번씩 참고하려고 포스팅한다.
"부정을 피하자"
코드에서는 긍정적인 표현식이 부정적인 표현식보다 훨씬 이해하기가 쉽다.
즉, Objects.nonNull(), !StringUtils.hasText() 등 보다 Objects.isNull(), StringUtils.hasText()가 좋다.
@Test
void goodRefactoring() {
Shiba shiba = null;
if(Objects.isNull(shiba)) {
System.out.println("Null 입니다.");
}
if(Objects.nonNull(shiba)) {
System.out.println("Null이 아닙니다.");
}
String empty = "";
if(StringUtils.hasText(empty)) {
System.out.println("text가 비어있지 않습니다.");
}
if(!StringUtils.hasText(empty)) {
System.out.println("text가 비어있습니다.");
}
}
"여러 조건은 간소화하자"
Boolean 조건이 여러 개 있으면 가독성이 좋지 않아서 복잡하고 읽기 어렵다.
조건이 3개 이상이라면 간소화를 고려해 보자.
@Test
void goodRefactoring() {
Shiba shiba = Shiba.builder().name("흑시바").age(20).color(Color.BLACK).build();
if(shiba.getName() == "흑시바" && shiba.getAge() >= 20 && shiba.getColor() == Color.BLACK) {
System.out.println("흑시바 입니다.");
}
}
이런 경우, 필드 값으로 빼거나 메서드로 만들어서 가독성을 높인다.
@Test
void goodRefactoring() {
Shiba shiba = Shiba.builder().name("흑시바").age(20).color(Color.BLACK).build();
if(isBlackShiba(shiba)) {
System.out.println("흑시바 입니다.");
}
}
private boolean isBlackShiba(Shiba shiba) {
return shiba.getName() == "흑시바" && shiba.getAge() >= 20 && shiba.getColor() == Color.BLACK;
}
"하드코딩된 문자열, 숫자는 상수로 대체한다"
코드에서 종종 문자열, 숫자를 하드 하게 작성하는 경우가 있다.
이러한 문자열, 숫자는 코드를 이해하기 어렵게 만들고 중복이 발생할 수 있다.
@Test
void goodRefactoring() {
Shiba shiba = Shiba.builder().name("흑시바").age(20).color(Color.BLACK).build();
if(shiba.getName().equals("흑시바")) {
System.out.println("흑시바1");
}
if(shiba.getName().equals("흑시바")) {
System.out.println("흑시바2");
}
if(shiba.getName().equals("흑시바")) {
System.out.println("흑시바3");
}
if(shiba.getAge() == 10) {
shiba.setRunning(274);
}
if(shiba.getAge() == 20) {
shiba.setRunning(322);
}
}
해당 코드를 보면 "흑시바"라는 문자열을 반복해서 검증하는 것을 볼 수 있다.
만약 어떤 경우에 의해서 "흑시바"가 아닌 "적시바" 등으로 변경할 경우 코드를 여러 번 고쳐야 하는 번거로움이 있다.
또한, 이렇게 변경해야 할 곳이 많은 경우 실수할 확률도 변경할 개수만큼 높아진다.
그리고 setRunning에 274와 322라는 숫자(매직 넘버)가 들어가 있는데,
다른 프로그래머가 코드를 봤을 때 274와 322라는 숫자가 무엇을 의미하는지 정확히 알 수 없기 때문에 setRunning에 대한 설명을 확인해야 하는 번거로움이 생긴다.
각 문자열, 숫자에 유의미하고 이해하기 쉬운 이름을 추가하면 의미가 명확해지고 실수할 확률도 줄어든다.
private static final String SHIBA = "흑시바";
private static final int BLACK_SHIBA_SPEED = 274;
private static final int BLACK_SHIBA_BOOST_SPEED = 274;
@Test
void goodRefactoring() {
Shiba shiba = Shiba.builder().name("흑시바").age(20).color(Color.BLACK).build();
if(shiba.getName().equals(SHIBA)) {
System.out.println("흑시바1");
}
if(shiba.getName().equals(SHIBA)) {
System.out.println("흑시바2");
}
if(shiba.getName().equals(SHIBA)) {
System.out.println("흑시바3");
}
if(shiba.getAge() == 10) {
shiba.setRunning(BLACK_SHIBA_SPEED);
}
if(shiba.getAge() == 20) {
shiba.setRunning(BLACK_SHIBA_BOOST_SPEED);
}
}
"정수 상수 대신 열거형을 사용하자"
확실히 매직 넘버(숫자)보다 상수가 훨씬 낫지만, 만약 값들에 연관된 의미가 있는 경우라면 열거형(Enum)을 사용하는 것이 훨씬 좋다.
private static final int WHITE = 1;
private static final int BLACK = 2;
private static final int YELLOW = 3;
@Test
void goodRefactoring() {
Shiba shiba = Shiba.builder().name("흑시바").age(20).color(1).build();
String color = getShibaColorName(4);
shiba.setColorName(color);
}
private String getShibaColorName(int color) {
if(color == WHITE) {
return "WHITE";
} else if(color == BLACK) {
return "BLACK";
} else if(color == YELLOW) {
return "YELLOW";
}
throw new IllegalArgumentException("잘못된 색상입니다.");
}
getShibaColorName() 메서드는 매개변수가 정수인 경우, 어떤 정수값이든 넣을 수 있다. 음수나 다른 정수 상수를 넣는 것도 가능하다. 반드시 1, 2, 3을 사용해야 한다고 컴파일러에서 강제하지 않기 때문이다.
getShibaColorName() 메서드는 파라미터에 1,2,3 외 값을 넣으면 호출 시점에 예외가 발생한다. 그러므로 문제가 발생한다는 걸 컴파일 과정에서 알 수가 없다. 또한, 만약 프로그램이 실행 중에 호출되지 않는 경우 한참 뒤에 발견되거나 영영 발견되지 않을 수 있다.
Enum을 사용하면 이러한 문제를 해결할 수 있다.
@Test
void goodRefactoring() {
Shiba shiba = Shiba.builder().name("흑시바").age(20).color(Color.BLACK).build();
String color = getShibaColorName(Color.BLACK);
shiba.setColorName(color);
}
private String getShibaColorName(Color color) {
if(color == Color.WHITE) {
return "WHITE";
} else if(color == Color.BLACK) {
return "BLACK";
} else if(color == Color.YELLOW) {
return "YELLOW";
}
throw new IllegalArgumentException("잘못된 색상입니다.");
}
'Programming > Refactoring' 카테고리의 다른 글
[Refactoring] 반복문에서 계산 연산을 주의하자(Pattern) (0) | 2023.03.12 |
---|---|
[Refactoring] 자바 API를 적극 활용하자 (0) | 2023.03.12 |
댓글