210223_B책_정수 상수 대신 열거형

정재현·2021년 2월 23일
0

TIL

목록 보기
75/80

어제에 이어서 예제 코드를 더 향상 시킬수 있는 방법에 대햐여 더 알아보겠다!

class CruiseControl { 
 static final int STOP_PRESET = 0;
 static final int PLANETARY_SPEED_PRESET = 1;
 static final int CRUISE_SPEED_PRESET = 2;
 
 static final int CRUISE_SPEED_KMH = 16994;
 static final int PLANETARY_SPEED_KMH = 7667;
 static final int STOP_SPEED_KMH = 0;
 
 private double targetSpeedKmh;
 
 void setPreset(int speedPreset) {
  if (speedPreset == CRUISE_SPEED_PRESET) {
   setTargetSpeedKmh(CRUISE_SPEED_KMH);
  } else if (speedPreset == PLANETARY_SPEED_PRESET) {
   setTargetSpeedKmh(PLANETARY_SPEED_KMH);
  } else if (speedPreset == STOP_PRESET) {
   setTargetSpeedKmh(STOP_SPEED_KMH);
  }
 }
 
 void setTargetSpeedKmh(double speed) {
  targetSpeedKmh = speed;
 }
}

어제 진행했던 것처럼 매직넘버보다 상수가 훨씬 낫다.
하지만~ 옵션을 모두 열거할 수 있다면 자바 타입 시스템이 제공하는 방법이 훨씬 낫다고 한다.

위의 코드에서 speedPreset은 아직 정수이다.
즉 어떤 정숫값이던 심지어 음수도 들어가서 setPreset()에 들어갈 수 있다는 뜻.
누구도 우리가 정의한 STOP_PRESET 같은 상수를 사용해야 한다고 강제하지 않습니다.
그리고 유효하지 않은 정숫값을 넣어도 아무도 뭐라고 안한다..
유효하지 않은 값이 들어와도 오류를 던지지 않고 그냥 반환한다.
충돌보다는 낫지만 이 말은 즉슨 어떤 버그 유형이든 야기할 수 있다는 뜻

자바와 같은 정적 타입 언어는 이러한 오류를 가능한 한 빨리 심지어 애당초 프로그램을
실행하기 전에 발견할 수 있는 기능을 제공한다!!
오류를 빨리 찾을 수록 고치는 비용도 낮아지고!

class CruiseControl { 
 private double targetSpeedKmh;
 
 void setPreset(SpeedPreset speedPreset) {
  Object.requireNonNull(speedPreset);
  
  setTargetSpeedKmh(speedPreset.speedKmh);
 }
 
 void setTargetSpeedKmh(double speedKmh) {
  targetSpeedKmh = speedKmh;
 }
}

  enum SpeedPreset {
   STOP(0), PLANETARY_SPEED(7667), CRUISE_SPEED(16994);

   final double speedKmh;

   SpeedPreset(double speedKmh) {
    this.speedKmh = speedKmh;
   }
  }
}

우선 Object.requireNonNull(speedPreset); 를 넣어
인자로 들어온 파라미터가 null이 아닌경우 다시 그대로 반환해주고 null인 경우 NullPointerException 예외를 발생시킨다.
위 코드처럼 가능한 옵션을 모두 열거할 수 있다면 항상 정수 대신 enum 타입을 사용하는 것이 좋다.
여기서는 SpeedPreset 이라는 새 enum을 생성하고 여기에 주어진 인스턴스의 speedKmh를 저장하는
변수 하나를 넣었습니다.
주요 장점은 존재하지 않는 SpeedPreset을 더 이상 setPreset() 메서드로 넣을 수 없다는 것.
또한 매직넘버가 아니라 의미있는 이름 그대로 참조할 수 있으며,
그 밖에 실제 targetSpeedKmh를 위한 상수도 이미 enum에 들어있어서 제거했다.
그리고 마지막으로 if else문 또한 제거할 수 있었다.
=>(예제 코드상으로 enum을 잘 사용한 것은 알겠는데 코드 전체적인 흐름이 잘 읽히지 않는다. 지금 좀 졸려서 그런건지..; 아니면 텍스트 그대로 봐서 그런건지는 모르겠는데 내일 한번 다시 보고 이해해야겠다. 뭐 아무튼 무슨 내용인지는 알겠다.)

오늘의 코멘트: 알았지만 정확히 알지 못했던 것들을 배워가니 좋다.

profile
"돈받고 일하면 프로다"

0개의 댓글