✍️ 악취 5 : 전역 변수(전역 데이터)
전역 변수, 가령 자바의 public static 변수는 어플리케이션 전반에 걸쳐서 접근하고 수정할 수 있기에 어느 위치에서 값이 참조되고 수정되는지 파악하기 어렵다. 이건 비단 전역 변수만의 문제가 아니라 클래스 필드도 그러하다. 클래스 필드가 외부에 public하게 노출되어 있다면 필드의 상태 변경을 파악하기 어려워진다.
전역 데이터를 위해 리팩토링을 활용할 수 있다.
1. 변수 캡슐화하기
🍊 변수 캡슐화하기
전역 변수와 클래스의 필드가 외부에 public하게 노출되어 참조 위치가 많아지면 상태 값을 추적하기 어렵다. 가령 단순 읽기 위해 변수를 참조했는지 값을 변경하기 위해 참조했는지 파악하기 어렵다. 게다가 변수에 값을 직접 할당하면 값에 대한 검증이 불가능하다.
변수의 조회와 변경을 별도의 메서드를 통해서만 가능하게 한다면 의도를 명확하게 분리할 수 있고 앞서 말한 값에 대한 검증 과정도 메서드 내에서 처리할 수 있다.
// before
public class AirConditioning {
public static int targetTemperature = 25;
// 제습 모드
public static boolean dehumidificationMode = true;
// 화씨로 표기
public static boolean readInFahrenheit = false;
}
public class App {
public static void main(String[] args) {
System.out.println(AirConditioning.targetTemperature);
AirConditioning.targetTemperature = -10000;
AirConditioning.dehumidificationMode = true;
AirConditioning.readInFahrenheit = false;
}
}
전역 변수를 private으로 변경하고 각각의 getter/setter로만 접근하도록 변경했다. 변수 사용 시 의도를 명확하게 분리할 수 있고 메서드 내부에 로직을 추가해서 코드의 응집력을 높이는 효과도 있다.
// after
public class AirConditioning {
private static int targetTemperature = 25;
// 제습 모드
private static boolean dehumidificationMode = true;
// 화씨로 표기
private static boolean readInFahrenheit = false;
public static Integer getTargetTemperature() {
if (readInFahrenheit)
return (int) (targetTemperature * 1.8 + 32);
return targetTemperature;
}
public static void setTargetTemperature(Integer targetTemperature) {
if (targetTemperature > 40 || targetTemperature < 10)
throw new IllegalArgumentException();
AirConditioning.targetTemperature = targetTemperature;
}
```
}
'리팩토링' 카테고리의 다른 글
[리팩토링] 악취 7 : 뒤엉킨 변경 (0) | 2022.12.19 |
---|---|
[리팩토링] 악취 6 : 가변 데이터 (0) | 2022.11.27 |
[리팩토링] 악취 4. 긴 매개변수 목록 (0) | 2022.11.06 |
[리팩토링] 악취 3. 긴 함수 (0) | 2022.10.30 |
[리팩토링] 악취 2. 중복 코드 (0) | 2022.10.29 |