상수의 병적 사용
왜 내가 써야 하는가?
import static org.apache.commons.lang.math.NumberUtils.INTEGER_ONE;
if (myIntVariable == INTEGER_ONE) { ... }
대신에:
if (myIntVariable == 1) { ... }
?
상수 사용이 권장된다는 것을 알고 있지만의 값 NumberUtils.INTEGER_ONE
은 절대 변하지 않을 것이라고 생각합니다 ! 그래서 나는 씁니다 1
.
당신은해야하지. INTEGER_ONE
그러나이 값이 다음 일정 (등을 이용하여, (올해 예를 들어, 월) 다른 의미가있는 경우 이름은 더 이상 의미가 1보다없는 Calendar.FEBRUARY
코드가 명확하게한다).
Commons Math 라이브러리의이 상수는 Integer 캐시와 오토 박싱이 없을 때 Java 1.4에서 생성되었다고 추측 할 수 있습니다 . 따라서 메모리를 절약하기 위해 다른 위치에서 동일한 Integer
객체 (원시가 int
아님)를 재사용 할 수 있다는 점에서 의미가있었습니다 . 따라서 코드 명확성이 아닌 성능상의 이유로 추가되었습니다. 이제는 쓸모가 없습니다. Integer
객체 가 필요한 경우에도 Integer.valueOf(1)
묵시적 오토 박싱을 사용 하거나 캐시 된 오토 박싱을 가져올 수 있습니다 .
당신은해야 하지 쓰기 INTEGER_ONE
! 또한 작성해서는 안됩니다 1
(아래 예외 참조)!
왜? 리터럴 같은 1
것을 매직 넘버 라고합니다 . 매직 넘버는 "설명 할 수없는 의미를 가진 고유 한 값이거나 (바람직하게는) 명명 된 상수로 대체 될 수있는 여러 번 발생"(동일한 Wikipedia 페이지의 설명)입니다.
그래서 일반적으로해야 할 일은 마법의 숫자를 이름이 그 숫자의 의미를 나타내거나 설명하는 상수로 만드는 것입니다. 상수 INTEGER_ONE
는 의미를 설명하지 않습니다.
따라서 실제로해야 할 일은이 컨텍스트에서 값의 의미를 찾고 정확히 그 이름을 가진 상수를 만드는 것입니다. 1
예를 들어 허용 된 스레드의 최대 수를 나타내는 경우 다음 과 같은 상수가 있어야합니다.
static final int MAX_NUMBER_OF_THREADS = 1;
Tagir의 의견에 따라 편집
리터럴 자체가 코드를 작성하는 도메인에서 의미가있는 경우 명명 된 상수로 대체해서는 안됩니다. 역 요소를 계산하는 Tagir의 예는 다음과 같습니다.
double invert(double x) {
return 1/x;
}
여기서 리터럴 1
은 수학 영역 내에서이 문맥에서 의미를 갖습니다. 따라서 그대로 사용할 수 있습니다.
저는 제 회사에 대한 스타일 지침을 방금 작성했으며 다음을 제안합니다.
하드 코딩 된 "마법"값을 사용하지 마십시오. 값이 상수이면 그대로 정의하십시오. -1, 0, 1, 2, 100과 같은 숫자는 일부 상황에서 사용될 수 있습니다.
내 예제는 Objective-C에 있습니다. 그것이 내가 지침을 작성했던 언어이지만 규칙은 여전히 적용됩니다.
좋은 사용법
static NSString* const DatabaseName = @"database.name";
//Acceptable use of "2"
float x = (ScreenWidth / 2) - (ImageWidth / 2);
//Acceptable use of 0
for (int i = 0; i < NumberOfItems; i++)
//Acceptable use of 100, but only because the variable is called "percentage"
float percentage = (someObjects * 100) / allObjects.count;
잘못된 사용
float x = (480 / 2) - (120 / 2); //We have to guess these are sizes?
//Unneccessary constants.
for (int i = ZERO; i < NumberOfItems; i += ONE)
float percentage = (someObjects.count * 100) / 120; //What is 120?
org.apache.commons.lang.math.NumberUtils.INTEGER_ONE
final static Integer
기본 int
1이 아닌 객체를 제공 하며, 그대로 final static
상수 역할을하며 Integer
항상 동일한 인스턴스를 반환하므로 객체 비교에 사용할 수 있습니다 .
따라서 위의 시나리오에서는 적합 하지 않을 수 있지만 비교하는 동안 사용하면 확실히 영향을 미칩니다.
더욱이, 우리가 할 수있는 한, 하드 코딩 된 것보다 상수 사용을 선호해야합니다 :
- 코드를 쉽게 유지 관리 할 수 있습니다. 향후 변화를위한 상황이 발생하면 한 곳에서만 변화가 가능합니다.
- 코드가 더 깨끗하고 읽기 쉬워 보입니다.
절대 변경되지 않을지 알 수 있지만 코드 편집을 시작하면 변경하지 않습니다.
Basically it's a way of documenting your code in your actual code. The reason to use constants and examples like this is to avoid Magic Numbers in code and their disadvantages.
This being said, you can use it to a point where it is not advantageous anymore and clutter inducing. I tend to do it for things that are used more than once or have the concept of being changed by me or someone else... or in simpler terms important values.
From Class NumberUtils you'll see it's defined as:
/** Reusable Integer constant for one. */
public static final Integer INTEGER_ONE = new Integer(1)
So, you'll see that INTEGER_ONE is not the same as 1. It's an object that's already been constructed for you. So, if we're needing an instance of Integer(1)
, rather than create your own, you can reuse the one from the library saving time and memory.
It really depends on your application, if you indeed what the int
version of 1, then, you'd probably be better of using that instead of this Integer
class.
Imagine that you have this
if (myIntVariable == 1) { ... }
But a few thousand times...
And suddenly in needs to be a 2.
What it easier for you to change?
EDIT: Before downvoting, im answering from the perspective of the advantages of not using magic numbers, im not in any way (i thought this was inferable, come on people) advising to change the library constant.
참고URL : https://stackoverflow.com/questions/31471444/morbid-use-of-constants
'programing tip' 카테고리의 다른 글
REST API : 단일 가져 오기에서 여러 리소스 요청 (0) | 2020.11.23 |
---|---|
AngularJS 지시문 동적 템플릿 (0) | 2020.11.23 |
androidx로 마이그레이션 한 후 androidx.constraintlayout.ConstraintLayout 클래스 확장 오류 (0) | 2020.11.23 |
C에서 참조로 배열을 전달합니까? (0) | 2020.11.23 |
언제 RuntimeException을 잡아도 괜찮습니까? (0) | 2020.11.23 |