2009-06-04 4 views
4

0, 1 또는 5과 같은 홀수 번호를 쉽게 잃어 버릴 수 있습니다. 나는 저수준의 C 코드를 작성했을 때 이것을 매우 엄격하게 사용했다. XML과 SQL에 관련된 모든 문자열 리터럴에 대해 더 많은 작업을 할 때마다 적어도 문자열 리터럴에 관해서는 코드에 상수를 포함하는 규칙을 종종 위반하는 경우가 있습니다. (저는 여전히 수치 상수에 대해 잘 알고 있습니다.)문자열 상수가 과대 평가 되었습니까?

문자열은 숫자와 같지 않습니다. 지루하고 약간 바보스럽고 (예 : const string NameField = "Name";) 같은 이름의 컴파일 타임 상수를 만드는 것은 어리석은 짓이며 많은 지역에서 동일한 문자열 리터럴을 반복하는 것이 위험한 것처럼 보이지만 오타가 발생할 가능성은 거의 없습니다. 복사 및 붙여 넣기를 할 때 리팩토링을 할 때 주위의 것들과 관련하여 기능적으로 어떻게 다루어 지는지와 같은 일을하는 것 이상의 이름을 바꾸는 일이 일반적입니다.

그럼, 좋은 XML 직렬 변환기가 없거나 설정하려는 기분이 아니라고 가정 해 봅시다. (당신이 어떤 코드 리뷰에서 또래 집단의 압력에 활을 시도되지 않은 경우)이 어떤 당신이 개인적으로 사용합니다 :

static void Main(string[] args) 
{ 
    // ...other code... 

    XmlNode node = ...; 

    Console.WriteLine(node["Name"].InnerText); 
    Console.WriteLine(node["Color"].InnerText); 
    Console.WriteLine(node["Taste"].InnerText); 

    // ...other code... 
} 

나 :

class Fruit 
{ 
    private readonly XmlNode xml_node; 

    public Fruit(XmlNode xml_node) 
    { 
     this.xml_node = xml_node; 
    } 

    public string Name 
    { get { return xml_node["Name"].InnerText; } } 

    public string Color 
    { get { return xml_node["Color"].InnerText; } } 

    public string Taste 
    { get { return xml_node["Taste"].InnerText; } } 
} 

static void Main(string[] args) 
{ 
    // ...other code... 

    XmlNode node = ...; 
    Fruit fruit_node = new Fruit(node); 

    Console.WriteLine(fruit_node.Name); 
    Console.WriteLine(fruit_node.Color); 
    Console.WriteLine(fruit_node.Taste); 

    // ...other code... 
} 
+2

0은 홀수가 아닙니다. 심지어는 :-) – paxdiablo

답변

0

당신은 아마 짐작대로입니다. 대답은 컨텍스트에 따라 다릅니다.

예제 코드가 무엇인지에 따라 다릅니다. 만약 작은 스로우 어웨이 시스템의 일부분이라면 상수를 하드 코딩하는 것이 허용 될 수 있습니다.

크고 복잡한 시스템의 일부이고 여러 파일에서 상수를 사용하는 경우 두 번째 옵션이 더 유용 할 것입니다.

0

프로그래밍의 많은 문제에서와 마찬가지로, 이것은 취향의 문제입니다. 적절한 프로그래밍의 "법칙"은 경험을 통해 만들어졌습니다. 많은 사람들이 네임 스페이스 또는 명료성 문제를 야기하는 글로벌 변수로 인해 불타 오므로 Global Variables Are Evil입니다. 많은 사람들이 마술 번호를 사용하여 나중에 그 번호가 잘못되었거나 변경 될 필요가 있음을 발견했습니다. 텍스트 검색은 이러한 값을 변경하는 데 적합하지 않으므로 Constants In Code Are Evil입니다.

가끔은 이 악의가 아니기 때문에 양쪽 모두 허용됩니다. 악. 결정을 스스로 내릴 필요가 있습니다 - 명확한 코드로 연결됩니까? 유지 보수 담당자에게는 어느 것이 더 좋을까요? 원래 규칙 뒤에있는 추론이 내 상황에 적용됩니까? 나중에이 코드를 읽거나 유지해야한다면 어떻게 쓰여졌 을까요?

두 프로그래머의 마음이 똑같이 작동하지 않기 때문에 절대적인 코딩 스타일은 없습니다. 규칙은 가능한 가장 명확하고 깨끗한 코드를 작성하는 것입니다.

0

개인적으로, 나는 사전에 XML 파일에서 열매를로드하는 것 - 같은 :

public class Fruit 
{ 
    public Fruit(string name, Color color, string taste) 
    { 
     this.Name = name; this.Color = color; this.Taste = taste; 
    } 

    public string Name { get; private set; } 
    public Color Color { get; private set; } 
    public string Taste { get; private set; } 
} 

// ... In your data access handling class... 
    public static FruitFromXml(XmlNode node) 
    { 
      // create fruit from xml node with validation here 
    } 
} 

그 방법은은 "열매"정말 스토리지에 연결되지 않습니다.

+0

좋은 조언이지만 질문에 대한 답변이 아닙니다. – jmucchiello

+0

@jmucchiello : 예, 아니오 - 답도 아닙니다. 진정한 상수는 아니며 값에 대한 XML 노드 "쿼리"에 대한 비법입니다. 두 옵션 모두 내 코드에서 선호하는 옵션이 아니므로 선호하는 것을 넣습니다. –

5

그런 식으로 상수가 얼마나 자주 사용되는지에 따라 다릅니다. 귀하의 예에 따라 하나의 장소에 있다면 하드 코딩이 좋습니다. 여러 다른 장소에서 사용되는 경우 반드시 상수를 사용하십시오. 컴파일러가 fruit_node 대신 fruit_node.Tsate를 입력했음을 알리는 반면, "맛"대신 "Tsate"를 입력했음을 알지 않으므로주의하지 않으면 한 시간의 오타가 디버깅 시간으로 이어질 수 있습니다. 미각.

편집 : 복사 및 붙여 넣기에 대해 언급 했으니까요. 그렇다면 처음부터 상수를 만들지 않고 저장하는 시간을 잃을 수도 있습니다. IntelliSense 및 자동 완성 기능을 사용하면 복사/붙여 넣기 문제를 해결하는 대신 몇 번의 키 입력으로 일정을 유지할 수 있습니다.

11

정의 된 상수는 리팩터링하기가 쉽습니다. "이름"이 세 번 사용 된 후이를 "FullName"으로 변경하면 상수를 변경하는 것은 세 가지가 아닌 하나의 변경입니다.

+0

OP의 요점은 전체 검색 및 바꾸기 (IDE 또는 텍스트 편집기에서)가 한 번에 3 개를 모두 잡아낼 것이라는 점입니다. – Eddie

+3

@Eddie, "Name"을 다른 모든 용도로 사용합니다. const string XmlNodeName = "Name"; const string AddressName = "Name"; const string XmlFruitName = "Name"; 어디서나 "이름"을 하드 코드하고 XmlNodeName 만 변경된 경우 어떻게해야합니까? –

+0

예 글로벌 검색 및 바꾸기는 하드 코딩 된 문자열을 사용하는 것보다 훨씬 위험합니다. 하드 코딩 된 문자열을 대체하는 데 사용될 때 더욱 그렇습니다. – Gerald

0

나는 상수와 함께 갈 것입니다. 조금 더 일이지만 성능에 미치는 영향은 없습니다. 그리고 값을 복사/붙여 넣기를하더라도, 필자는 입력 할 때 코드를 변경하고 Visual Studio에 포커스가 있다는 것을 인식하지 못했습니다. 나는 을 많이 받았다.이 결과는 컴파일 에러가 발생했다.

0

예를 들어, 문자열을지도 또는 사전의 키로 사용하는 경우 대신 enum (또는 다른 객체)을 사용해야합니다. enum을 사용하면 상수 문자열을 사용하는 것보다 훨씬 많은 작업을 수행 할 수 있습니다. 또한 일부 코드가 주석 처리 된 경우 IDE에서 리팩토링을 수행 할 때 실수로 빠지기 쉽습니다. 또한 주석에있는 문자열 상수에 대한 참조는 리팩터에 포함되거나 포함되지 않을 수 있습니다.

문자열이 여러 위치에서 사용될 때 문자열이 길거나 복잡 할 때 (정규식과 같이) 또는 제대로 명명 된 상수가 코드를보다 분명하게 만들 때 문자열에 상수를 만듭니다.

필자는 필자의 오타, 불완전한 리팩터링 및 기타 버그를 적절하게 조작하지 못하고 컴파일하는 것을 선호합니다.

0

다른 많은 리펙토링과 마찬가지로, 그것은 유지 관리에 덜 위험하고 "다음 사람"이 더 쉽게 코드를 남길 수있는 선택적인 추가 단계입니다. 당신이 그런 종류의 것을 보상하는 상황에 있다면 (내가 할 일 중 대부분), 그걸로 가십시오.

0

예, 꽤 많이.

정적으로 입력 된 언어의 개발자는 모든 역동성에 대해 건강에 좋지 않은 두려움을 갖고 있다고 생각합니다. 동적으로 타입이 지정된 언어의 코드 라인은 사실상 문자열 리터럴이며, 수년 동안 괜찮 았습니다. 예를 들어, 자바 스크립트에서 기술적으로이 :

var x = myObject.prop1.prop2; 

은 다음과 동일합니다 :

var x = window["myObject"]["prop1"]["prop2"]; // assuming global scope 

을하지만 자바 스크립트의 표준 연습이 일을 확실히 하지입니다 :

var OBJ_NAME = "myObject"; 
var PROP1_NAME = "prop1"; 
var PROP2_NAME = "prop2"; 

var x = window[OBJ_NAME][PROP1_NAME][PROP2_NAME]; 

그것은 어리 석다.

문자열은 여러 위치에서 사용되는 것과 마찬가지로 입력하기가 번거롭고 ("name"대 "my-custom-property-name-x") 번거롭기 때문에 여전히 달라질 수 있습니다. 단일 클래스 내에서도 상수 일 수 있습니다 (어느 시점에서 클래스 내에서 내부적으로 일관성이 있고 다른 모든 문자열을 상수로 만들 수도 있습니다).

또한 실제로 다른 외부 사용자가이 상수를 사용하여 라이브러리와 상호 작용하려는 경우 공개적으로 액세스 할 수있는 상수를 정의하고 사용자가 라이브러리와 상호 작용하는 데 사용하도록 문서화하는 것이 좋습니다. 그러나 마술 문자열 상수를 통해 상호 작용하는 라이브러리는 일반적으로 좋지 않으므로 처음에는 마법 상수를 사용할 필요가 없도록 라이브러리를 설계하는 것이 좋습니다.

문자열을 상대적으로 간단하게 입력 할 수 있고 API의 외부 사용자가 문자열 값을 사용하여 작업 할 것으로 예상되는 외부 사용자가없는 경우 (예 : 내부 용 데이터 조작), 읽을 수있는 코드는 리팩토러블 코드보다 훨씬 더 가치가 있기 때문에 리터럴을 직접 인라인에 넣을 수 있습니다. 다시 말하지만, 이것은 귀하의 정확한 유스 케이스를 구체적으로 이해하고 있다고 가정합니다.

아무도 눈치 채지 못한 것 중 하나는 상수를 정의하자마자 그 범위가 유지되고 생각할 수있는 것이된다는 것입니다. 실제로 에 비용이 들지만 모두가 생각하는 것처럼 무료는 아닙니다. 이것을 고려하십시오 :

내 수업에는 비공개 또는 공개해야합니까? 만약 다른 어떤 네임 스페이스/패키지가 같은 값을 필요로한다면, 상수를 전역 정적 클래스의 일부로 추출해야합니까? 다른 어셈블리/모듈에서 필요하면 어떻게합니까? 이 모든 것들이 코드를 읽기 쉽고 읽기 쉽고, 유지하기가 어렵고, 작업하기가 쉽지 않으며, 복잡합니다. 모두는 리팩토링 성의 이름입니까?

일반적으로 이러한 "위대한 리팩토링"은 결코 발생하지 않으며, 어쨌든 완전히 새로운 모든 문자열을 사용하여 다시 작성해야합니다. 그리고 만약 여러분이 지금 필요로하는 새로운 문자열을 가지고 있지 않은이 위대한 리팩토링 (위의 단락에서) 전에 공유 모듈을 사용했다면, 그 때 무엇을 했습니까? 그것들을 동일한 공유 모듈 상수에 추가합니까? (이 공유 모듈의 코드에 액세스 할 수 없다면 어떻게됩니까?) 또는 당신이 그들에게 국부적으로 두었을 때, 코드 상에 중복 된 상수의 위험을 안고있는, 문자열 상수의 여러 흩어져있는 저장소가 서로 다른 레벨에 존재합니다. 이 지점에 도착 (나 내가 본 적이 믿을 수) 후에는 당신의 상수의 모든 당신의 용도를 얻을 수 있습니다 동안, 당신은 다른명의 용도를 그리워 것이기 때문에, 리팩토링, 논쟁하게 자신의 상수.이 상수는 상수와 동일한 논리 값을 가지고 있으며 실제로 모든 상수를 변경하려고합니다.

관련 문제