애플리케이션에 값을 하드 코딩하는 것이 좋은 생각입니까? 또는 이러한 유형의 값을 변경해야 할 경우를 대비하여 동적으로 호출하는 것이 항상 올바른 것입니까?
답변
답변
지금까지이 Q & A에서 이상한 점을 발견 한 사람은 실제로 아무도 “하드 코드”또는 더 중요한 대안을 명확하게 정의하려고 시도하지 않았다는 것입니다.
TL; DR : 예, 그것은 이다 하드 코드 값에 좋은 생각이 가끔 있지만,에 관해서는 간단한 규칙이 없다 경우는 , 그것은 상황에 전적으로 달려 있습니다.
질문은 값을 좁히는 데 , 이는 마법의 숫자 를 의미 하지만, 그들이 좋은 아이디어인지 아닌지에 대한 대답 은 실제로 사용되는 것과 관련이 있습니다 !
“하드 코딩 된”값의 몇 가지 예는 다음과 같습니다.
-
구성 값
나는 같은 문장을 볼 때마다 울었다
command.Timeout = 600. 왜 600입니까? 누가 결정 했습니까? 시간이 초과되어 누군가가 기본 성능 문제를 해결하는 대신 해킹으로 시간 초과를 제기 했습니까? 아니면 실제로 처리 시간에 대한 일부 알려진 문서화 된 기대입니까?이들은 마법의 숫자 나 상수 가 아니 어야합니다. 최적의 값은 응용 프로그램이 실행되는 환경에 의해 대부분 또는 전적으로 결정되므로 의미있는 이름으로 구성 파일이나 데이터베이스에서 외부화해야합니다.
-
수학 공식
공식은 일반적으로 정적 인 경향이 있으므로 내부의 상수 값의 특성이 실제로 중요하지 않습니다. 피라미드의 부피는 (1/3) b * h입니다. 우리는 1 또는 3이 어디에서 왔는지 걱정합니까? 실제로는 아닙니다. 이전의 주석가는
diameter = radius * 2아마 그보다 더 낫다고 지적diameter = radius * RADIUS_TO_DIAMETER_CONVERSION_FACTOR했지만 그것은 거짓 이분법입니다.이 유형의 시나리오에서 수행해야 할 일은 함수를 작성하는 것 입니다. 나는 당신 이 공식을 어떻게 만들 었는지 알 필요는 없지만 여전히 그것이 무엇인지 알아야 합니다 . 위에서 쓴 넌센스 대신에
volume = GetVolumeOfPyramid(base, height)갑자기 모든 것이 훨씬 명확 해지 며 함수 안에 마법의 숫자 (return base * height / 3)가 있으면 수식의 일부라는 것이 분명하기 때문에 완벽하게 괜찮습니다 .열쇠는 여기에 가지고 물론이고 짧은 및 간단한 기능을. 10 개의 인수와 30 개의 계산 라인이있는 함수에서는 작동하지 않습니다. 이 경우 함수 구성 또는 상수를 사용하십시오.
-
도메인 / 비즈니스 규칙
이것은 값이 정확히 무엇인지에 따라 다르므로 항상 회색 영역입니다. 대부분 의 경우 상수로 변하는 후보가되는 이러한 특정 매직 번호입니다. 프로그램 논리를 복잡하게하지 않고도 프로그램을 더 쉽게 이해할 수 있기 때문입니다. 테스트
if Age < 19대if Age < LegalDrinkingAge.; 당신은 아마도 상수없이 무슨 일이 일어나고 있는지 알아낼 수 있지만 설명적인 제목으로 더 쉽습니다.이것들은 또한 예를 들어 함수 추상화의 후보가 될 수 있습니다
function isLegalDrinkingAge(age) { return age >= 19 }. 유일한 것은 비즈니스 로직이 그보다 훨씬 복잡하다는 것입니다. 각각 20-30 개의 매개 변수로 수십 개의 함수를 작성하는 것이 이치에 맞지 않을 수 있습니다. 객체 및 / 또는 함수를 기반으로 명확한 추상화가 없으면 상수를 사용하는 것이 좋습니다.주의해야 할 점은 세무 부서에서 일하는 경우 실제로 부담스럽고 솔직하게 쓸 수 없게됩니다
AttachForm(FORM_CODE_FOR_SINGLE_TAXPAYER_FILING_JOINTLY_FOR_DEPRECIATION_ON_ARMPIT_HAIR). 당신은 그렇게하지 않을 것입니다. 당신AttachForm("B-46")은 일을했거나 일할 모든 개발자가 “B-46″이 단일 납세자 신고를위한 형식 코드라는 것을 알게 될 것입니다. 양식 코드는 도메인 자체의 일부이므로 절대 변경되지 않으므로 실제로 마법의 숫자가 아닙니다.따라서 비즈니스 로직에서 상수를 조금만 사용해야합니다. 기본적으로 “매직 넘버”가 실제로 매직 넘버인지 또는 잘 알려진 도메인인지 이해해야합니다. 도메인 인 경우 변경 될 가능성이없는 한 소프트 코딩하지 않습니다.
-
오류 코드 및 상태 플래그
혹시라도 맞은 가난한 나쁜 놈이 당신에게 말할 수 있듯이, 이것들은 하드 코딩하기에는 결코 괜찮지 않습니다
Previous action failed due to error code 46. 언어가 지원하는 경우 열거 형을 사용해야합니다. 그렇지 않으면 일반적으로 특정 오류 유형에 유효한 값을 지정하는 상수로 가득 찬 전체 파일 / 모듈이 있습니다.return 42오류 처리기에서 보지 못하게 하시겠습니까? 변명하지.
아마 몇 가지 시나리오를 생략했지만 그 중 대부분을 다루고 있다고 생각합니다.
그렇습니다. 때로는 하드 코딩하는 것이 좋습니다. 그것에 대해 게으르지 마십시오. 평범한 엉성한 코드보다는 의식적인 결정이어야합니다.
답변
식별자를 숫자에 할당하는 데는 여러 가지 이유가 있습니다.
- 숫자가 변경 될 수 있으면 식별자가 있어야합니다. 9의 모든 인스턴스를 검색하고 8로 변경해야하는지 여부를 고려하는 것보다 NUMBER_OF_PLANETS를 찾는 것이 훨씬 쉽습니다. (소프트웨어를 다른 언어로 사용해야하는 경우 사용자가 볼 수있는 문자열을 변경해야 할 수도 있습니다. 미리 예측하기 어려운 것.)
- 숫자가 어떤 식 으로든 입력하기 어려운 경우 pi와 같은 상수의 경우 여러 위치에 부정확하게 다시 입력하는 것보다 하나의 최대 정밀도 정의를 제공하는 것이 좋습니다.
- 번호가 다른 장소에서 발생하는 경우. 인접한 함수에서 45의 두 가지 용도를 살펴볼 필요가 없으며 동일한 기능을 의미하는지 궁금합니다.
- 의미를 즉시 인식 할 수없는 경우 모든 사람이 3.14159265 …가 무엇인지 알고 있다고 가정하는 것이 안전합니다. 모든 사람이 중력 상수 또는 pi / 2를 인식한다고 가정하는 것은 안전하지 않습니다. (여기서 “모두”는 소프트웨어의 특성에 따라 다릅니다. 시스템 프로그래머는 유닉스 허가 비트 등의 8 진 표현을 알고 있어야합니다. 해군 / 해상 아키텍처 소프트웨어에서 제안 된 선체의 Froude 수와 속도를 1.1 이상인 경우 작업해야하는 사람에게 완벽하게 설명이 필요한지 확인하십시오.)
- 컨텍스트를 인식 할 수없는 경우 모든 사람은 한 시간에 60 분이 있다는 것을 알고 있지만 수량이 시간 값 또는 요율 값이라는 즉각적인 표시가 없으면 60을 곱하거나 나누는 것이 명확하지 않을 수 있습니다.
이것은 우리에게 하드 코딩 리터럴에 대한 기준을 제공합니다. 한 곳이나 상황에서만 발생하며 인식 할 수있는 의미로 불변의 형태로 입력하기 어렵지 않아야합니다. 예를 들어 0을 ARRAY_BEGINNING으로 정의하거나 1을 ARRAY_INCREMENT로 정의 할 필요는 없습니다.
답변
다른 답변에 추가하여. 가능하면 문자열에 상수를 사용하십시오. 물론, 당신은 갖고 싶지 않아
const string server_var="server_var";
하지만 당신은해야합니다
const string MySelectQuery="select * from mytable;";
(실제로 특정 테이블에서 모든 결과를 얻으려는 쿼리가 실제로 있다고 가정하면)
그 외에는 0 (보통) 이외의 숫자에 상수를 사용하십시오. 255의 권한 비트 마스크가 필요한 경우 사용하지 마십시오
const int 8th_bit=255; //or some other obscure naming scheme that equates to 255.
대신에 사용
const int AllowGlobalRead=255;
물론 상수와 함께 열거자를 언제 사용할지 알아야합니다. 위의 경우는 아마도 하나에 잘 맞을 것입니다.
답변
하드 코딩 고려 사항에 따라 다릅니다. 하드 코딩 된 모든 항목을 피하려고하면 소프트 코딩 영역 이 생겨서 제작자 만 관리 할 수있는 시스템을 구축하게됩니다 (그리고 이것이 궁극적 인 하드 코드입니다).
많은 것들이 합리적인 프레임 워크로 하드 코딩되어 작동합니다. 즉, C # 응용 프로그램 (static void Main)의 진입 점을 변경할 수 없어야하는 기술적 인 이유는 없지만 어떤 사용자에게도 문제를 일으키지 않는 하드 코딩 (때로는 SO 질문 제외 )
내가 사용하는 경험의 규칙은 전체 시스템의 상태에 영향을 미치지 않고 변경 될 수있는 것과 변경 될 수있는 것은 모두 혼동 가능해야한다는 것입니다.
따라서 IMHO, 절대 변하지 않는 것들 (pi, 중력 상수, 수학 공식의 상수-구의 부피)을 하드 코딩하지 않는 것은 어리석지 않습니다.
또한 어떤 경우 든 프로그래밍이 필요한 시스템에 영향을 미치는 사물이나 프로세스를 하드 코딩하지 않는 것은 바보 같은 일이 아닙니다. 즉, 추가 된 필드에 유지 보수 개발자가 들어가서 작동시킬 스크립트를 작성하십시오. 또한 일부 구성 도구를 만드는 것은 어리 석고 (엔터프라이즈 환경에서는 몇 번 보았습니다) 하드 코딩 된 것은 없지만 IT 부서의 개발자만이 사용할 수 있으며 사용하는 것보다 약간 더 쉽습니다 Visual Studio에서 수행하십시오.
결론적으로, 물건을 하드 코딩해야하는지 여부는 두 변수의 함수입니다.
- 가치가 변할 것인가
- 가치의 변화가 시스템에 어떤 영향을 미치는가
답변
애플리케이션에 값을 하드 코딩하는 것이 좋은 생각입니까?
값이 사양 (사양의 최종 릴리스에서) 에 지정된 경우 에만 값을 하드 코딩합니다 . 예를 들어 HTTP OK 응답은 항상 (RFC에서 변경되지 않는 한)이므로 ) 상수 :200
public static final int HTTP_OK = 200;
그렇지 않으면 속성 파일에 상수를 저장합니다.
내가 사양을 지정한 이유는 사양의 상수를 변경하려면 변경 관리가 필요하기 때문에 이해 관계자가 변경을 검토하고 승인 / 승인하지 않기 때문입니다. 밤새 일어나지 않으며 승인에 몇 개월 / 년이 걸립니다. 많은 개발자가 사양 (예 : HTTP)을 사용하므로 변경하면 수백만 개의 시스템이 손상된다는 것을 잊지 마십시오.
답변
- 값이 변경 될 수 있고 실제로 변경 될 수있는 경우 관련 노력이 예상 수익을 초과하지 않는 한 가능할 때마다 소프트 코딩하십시오.
- 일부 값 은 소프트 코딩 할 수 없습니다 . 그러한 (희귀 한) 경우에 Jonathan의 지침을 따르십시오