리팩토링 - 냄새 5. 전역 데이터

김상운(개발둥이)·2022년 4월 2일
0

리팩토링

목록 보기
6/17
post-thumbnail

들어가기

해당 포스팅은 인프런 백기선님의 '리팩토링'을 학습 후 정리한 내용입니다.



냄새 5. 전역 데이터

Global Data

  • 전역 데이터 (예, 자바의 public static 변수)
  • 전역 데이터는 아무곳에서나 변경될 수 있다는 문제가 있다.
  • 어떤 코드로 인해 값이 바뀐 것인지 파악하기 어렵다.
  • 클래스 변수 (필드)도 비슷한 문제를 겪을 수 있다.
  • 변수 캡슐화하기 (Encapsulate Variable)”를 적용해서 접근을 제어하거나 어디서 사용하는지 파악하기 쉽게 만들 수 있다.
  • 파라켈수스의 격언, “약과 독의 차이를 결정하는 것은 사용량일 뿐이다.”

변수 캡슐화하기

Encapsulate Variable

  • 메소드는 점진적으로 새로운 메소드로 변경할 수 있으나, 데이터는 한번에 모두 변경해야 한다.
  • 데이터 구조를 변경하는 작업을 그보다는 조금 더 수월한 메소드 구조 변경 작업으로 대체 할 수 있다.
  • 데이터가 사용되는 범위가 클수록 캡슐화를 하는 것이 더 중요해진다.
  • 함수를 사용해서 값을 변경하면 보다 쉽게 검증 로직을 추가하거나 변경에 따르는 후속 작업을 추가하는 것이 편리하다.
  • 불변 데이터의 경우에는 이런 리팩토링을 적용할 필요가 없다

예제 코드

public class Thermostats {

    public static Integer targetTemperature = 70;

    public static Boolean heating = true;

    public static Boolean cooling = false;

    public static Boolean fahrenheit = true;

public static void main(String[] args) {
        System.out.println(Thermostats.targetTemperature);
        Thermostats.targetTemperature = -1111600;
        Thermostats.fahrenheit = false;
    }

}

🤧 냄새

전역 변수인 targetTemperature 을 외부에서 변경할 수 있다.

💡 해결

객체 내부 필드의 접근 제한자를 private 으로 수정 후 변경 작업 시 메서드를 통해 변경하자!

리팩토링 후


public class Thermostats {

    private static final Integer targetTemperature = 70;

    private static Boolean heating = true;

    private static Boolean cooling = false;

    private static Boolean readInFahrenheit = true;

    public static Integer getTargetTemperature() {
        return targetTemperature;
    }

    public static void setTargetTemperature(Integer targetTemperature) {
        //TODO validation
        Thermostats.targetTemperature = targetTemperature;
    }

    public static Boolean getHeating() {
        return heating;
    }

    public static void setHeating(Boolean heating) {
        Thermostats.heating = heating;
    }

    public static Boolean getCooling() {
        return cooling;
    }

    public static void setCooling(Boolean cooling) {
        Thermostats.cooling = cooling;
    }

    public static Boolean getReadInFahrenheit() {
        return readInFahrenheit;
    }

    public static void setReadInFahrenheit(Boolean readInFahrenheit) {
        Thermostats.readInFahrenheit = readInFahrenheit;
    }
}

📣 설명

모든 필드에 대해 getter, setter 를 메서드를 추가하여 필드에 직접 접근하지 않고 메서드를 통해 데이터에 접근한다. targetTemperature 는 수정이 불가능하게 final 로 바꾼다.

profile
공부한 것을 잊지 않기 위해, 고민했던 흔적을 남겨 성장하기 위해 글을 씁니다.

0개의 댓글