명명 문제 : "문제"의 이름이 "뭔가"로 바뀌어야합니까? [닫은]


68

Clean Code의 이름에 대한 Bob Uncle 장의 이름은 주로 헝가리 표기법에 관한 이름의 인코딩을 피하는 것이 좋습니다. 또한 I인터페이스 에서 접두사를 제거하는 것에 대해 구체적으로 언급 하지만 이에 대한 예제는 표시하지 않습니다.

다음을 가정 해 봅시다.

  • 인터페이스 사용은 주로 의존성 주입을 통해 테스트 가능성을 달성하는 것입니다.
  • 대부분의 경우 단일 구현 자와 단일 인터페이스를 갖습니다.

예를 들어이 두 가지의 이름은 무엇입니까? Parser그리고 ConcreteParser? Parser그리고 ParserImplementation?

public interface IParser {
    string Parse(string content);
    string Parse(FileInfo path);
}

public class Parser : IParser {
     // Implementations
}

아니면 이와 같은 단일 구현 사례 에서이 제안을 무시해야합니까?


30
그렇다고해서 종교가되는 것은 아닙니다. 당신은 이유를 찾아 야지, 그냥 누군가 X는 Y를 말한다
마이크 Dunlavey

35
@MikeDunlavey 그리고 이것이 질문의 이유입니다!
Vinko Vrsalovic

14
다시 작성하지 않을 기존 코드 본문이 있으면 사용하는 규칙을 따르십시오. 새로운 코드라면, 작업 할 사람들의 대다수가 가장 행복하고 익숙한 것을 사용하십시오. 위의 어느 것도 적용되지 않는 경우에만 철학적 질문이되어야합니다.
TripeHound

9
@TripeHound 과반수 규칙이 항상 최선의 선택은 아닙니다. 어떤 것이 다른 것보다 더 좋은 이유가 있다면, 한 사람이 그 이유를 근거로 팀의 나머지 부분을 설득 할 수 있습니다. 맹목적으로 리드를 통해 물건을 평가하지 않고 대다수에게 맹목적으로 제출하십시오. 나는이 구체적인 사례에 대해 Is를 제거할만한 이유가 없지만 처음에 요청한 것을 무효화하지는 않는다는 대답에서 알 수 있습니다.
Vinko Vrsalovic

35
"Uncle Bob 's"책은 C #이 아닌 JAVA에 중점을 둡니다. 대부분의 패러다임은 C #과 동일하지만 일부 명명 규칙이 다릅니다 (Java의 lowerCamelCase 함수 이름도 확인). C #으로 쓸 때는 C # 명명 규칙을 사용하십시오. 그러나 어쨌든, 그의 장의 주요 이름 인 아이템의 의미를 전달하는 읽을 수있는 이름을 따르십시오!
Bernhard Hiller

답변:


191

"Uncle Bob"을 포함하여 많은 사람들 I이 인터페이스의 접두사 로 사용하지 말 것을 권장하지만 그렇게하는 것은 C #에서 잘 확립 된 전통입니다. 일반적으로 피해야합니다. 그러나 C #을 작성하는 경우 해당 언어의 규칙을 따르고 사용해야합니다. 그렇게하지 않으면 코드를 읽으려고하는 C #에 익숙한 다른 사람과 혼동 될 수 있습니다.


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
maple_shaft

9
"일반적으로 피해야합니다"에 대한 근거를 제공하지 않습니다. Java에서는 피해야합니다. C #에서는이를 수용해야합니다. 다른 언어는 자체 규칙을 따릅니다.
기본

4
"일반적인 용어"원칙은 간단합니다. 클라이언트는 인터페이스 또는 구현과 대화하고 있는지 알지 못할 권리가 있습니다. 두 언어 모두 잘못되었습니다. C #에서 명명 규칙이 잘못되었습니다. Java에서 바이트 코드가 잘못되었습니다. Java에서 동일한 이름의 인터페이스로 구현을 전환하면 이름과 메소드가 변경되지 않았어도 모든 클라이언트를 다시 컴파일해야합니다. "독을 뽑아 라"는 것이 아닙니다. 우리는 방금 잘못하고 있습니다. 새로운 언어를 만들고 있다면 이것으로부터 배우십시오.
candied_orange

39

인터페이스는 중요한 논리적 개념이므로 인터페이스에는 일반 이름이 있어야합니다. 그래서 나는 오히려

interface Something
class DefaultSomething : Something
class MockSomething : Something

...보다

interface ISomething
class Something : ISomething
class MockSomething : ISomething

후자는 몇 가지 문제가 있습니다.

  1. 무언가는 ISomething의 한 가지 구현 일 뿐이지 만, 그것이 마치 특별한 것처럼 일반적인 이름을 가진 것입니다.
  2. MockSomething은 무언가에서 파생 된 것처럼 보이지만 ISomething을 구현합니다. 어쩌면 MockISomething이라는 이름이 있어야하지만 야생에서는 결코 본 적이 없습니다.
  3. 리팩토링이 더 어렵다. 무언가가 지금 클래스이고 나중에 인터페이스를 소개해야한다는 것을 알게되면 유형이 구체적 클래스인지 추상 클래스인지 인터페이스인지 클라이언트에게 투명해야하기 때문에 해당 인터페이스의 이름이 동일해야합니다. . 문제가 발생합니다.

59
C #이 제공하는 잘 확립 된 표준을 따르지 않는 이유는 무엇입니까? 이로 인해 당신을 따르는 모든 C # 프로그래머를 혼란스럽고 자극하는 비용을 초과하는 이점이 있습니까?
Robert Harvey

6
@wallenborn 괜찮습니다.하지만 실제로는 단위 테스트에서 모의 ​​성을 위해 인터페이스를 사용하는 것이 일반적이기 때문에 인터페이스의 합법적 인 단일 구현 만있는 경우가 많습니다. 내가 넣어 싶지 않아 DefaultReal또는 Impl내 클래스 이름의 많은에
벤 아 론슨

4
나는 당신에 동의하지만, 당신 이이 길을 여행한다면 당신은 C #을 위해 만든 모든 린터와 싸워야 할 것입니다.
RubberDuck

3
인터페이스를 구현하는 대다수의 인스턴스가 해당 클래스라면 인터페이스와 동일한 이름을 가진 인스턴스화 가능한 클래스를 갖는 데 아무런 문제가 없습니다. 예를 들어, 많은 코드는 간단한 범용 구현이 필요하며 IList<T>실제로 내부에 저장되는 방식을 신경 쓰지 않습니다. 단지의 베다 할 수있는 I및 사용 가능한 클래스 이름은 마술 (자바로)의 일반적인 구현하고자하는 그 코드를 알고하는 것보다 더 좋은 것 같다가 List<T>사용해야을 ArrayList<T>.
supercat

2
@ArtB 몇 가지 이유. 첫째, 컨벤션이 클래스에서 좋은 짧은 마커 인 언어는 없습니다 CFoo : Foo. 따라서 해당 옵션을 실제로 사용할 수 없습니다. 일부 클래스는 마커를 것 등이 있는지 여부에 따라 것은 없기 때문에 두, 당신은 이상한 불일치를 얻을 수있는 동일한 인터페이스의 다른 구현합니다. CFoo : Foo하지만 SqlStore : Store. 그것은 내가 가진 하나의 문제이며 Impl, 이는 본질적으로 추한 마커입니다. 어쩌면 항상C (또는 무엇이든) 추가하는 관습이있는 언어가 있다면 , 그보다 더 좋을 것입니다.I
Ben Aaronson

27

이것은 단지 명명 규칙에 관한 것이 아닙니다 . C #은 다중 상속을 지원하지 않으므로 이러한 헝가리 표기법의 레거시 사용은 기본 클래스에서 상속하고 하나 이상의 인터페이스를 구현할 때 유용한 이점을 제공합니다. 그래서 이건...

class Foo : BarB, IBarA
{
    // Better...
}

... 이것보다 바람직하다 ...

class Foo : BarB, BarA
{
    // Dafuq?
}

IMO


7
그것은 자바 깔끔하게 클래스 상속과 인터페이스 구현, 즉 서로 다른 키워드를 사용하여이 문제를 피할 수 있음을 주목할 필요가 inheritsimplements.
Konrad Rudolph

6
@KonradRudolph 당신은 의미한다 extends.
OrangeDog

2
@Andy 부가 가치는 헝가리 표기법의 허풍을 피할 수는 있지만이 답변에서 선 명한 모든 명확성을 유지한다는 것입니다.
Konrad Rudolph

2
혼란이 없어야합니다. 클래스를 상속받는 경우 구현 된 인터페이스 목록보다 먼저 클래스가 목록에 있어야합니다. 나는 이것이 컴파일러에 의해 시행된다고 확신한다.
Andy

1
@Andy ... 클래스를 상속 받았다면 반드시 목록에서 제일 먼저 나와야합니다 . 훌륭하지만 접두사가 없으면 몇 개의 인터페이스 또는 기본 클래스와 인터페이스를 다루고 있는지 알 수 없습니다 ...
Robbie

15

아니, 아니.

명명 규칙은 Bob 아저씨 팬덤의 기능이 아닙니다. 언어, c # 등의 함수가 아닙니다.

그것들은 코드베이스의 기능입니다. 상점의 훨씬 적은 범위까지. 다시 말해, 코드베이스의 첫 번째는 표준을 설정합니다.

그래야 결정을 내릴 수 있습니다. 그 후에는 일관성이 있습니다. 누군가 불일치하기 시작하면 너프 총을 빼내고 회개 할 때까지 문서를 업데이트하도록합니다.

새 코드베이스를 읽을 때 I언어에 관계없이 접두사가 표시되지 않으면 괜찮습니다. 모든 인터페이스에서 하나를 보면 괜찮습니다. 때때로 하나를 보게되면 누군가가 지불하게됩니다.

코드 기반을 위해이 선례를 설정하는 희소 한 맥락에서 자신을 발견하면 이것을 고려해야합니다.

고객 클래스로서 나는 내가 말하고있는 것을 망설이지 않을 권리를 보유합니다. 필요한 것은 이름과 그 이름에 대해 부를 수있는 것들의 목록입니다. 내가 그렇게 말하지 않으면 변경되지 않을 수 있습니다. 나는 그 부분을 소유한다. 내가 말하고있는 것은 인터페이스 여부와 관계없이 내 부서가 아닙니다.

I그 이름으로 몰래 들어가면 고객은 신경 쓰지 않습니다. 이 없으면 I클라이언트는 신경 쓰지 않습니다. 그것이 말하는 것은 구체적 일 수 있습니다. 그렇지 않을 수도 있습니다. new어떤 식 으로든 호출하지 않기 때문에 아무런 차이가 없습니다. 클라이언트로서, 나는 모른다. 알고 싶지 않습니다.

이제 자바에서도 코드를 보는 코드 원숭이로서 이것이 중요 할 수 있습니다. 결국, 구현을 인터페이스로 변경 해야하는 경우 클라이언트에게 알리지 않고 그렇게 할 수 있습니다. I전통 이 없으면 이름을 바꾸지 못할 수도 있습니다. 소스가 바이너리를 신경 쓰지 않아도 클라이언트를 다시 컴파일해야하기 때문에 문제가 될 수 있습니다. 이름을 변경하지 않은 경우 놓치기 쉬운 것.

아마도 그것은 당신에게 문제가되지 않을 것입니다. 아마. 그렇다면 치료해야 할 좋은 이유입니다. 그러나 책상 장난감을 좋아한다고해서 우리가 맹목적으로 수행 해야하는 방식이기 때문에 맹목적으로해야한다고 주장하지 않습니다. 타당한 이유가 있거나 상관하지 않습니다.

영원히 함께 사는 것이 아닙니다. 어디에서나 '문제'를 고치기 위해 준비하지 않으면 특정 정신에 맞지 않는 코드베이스에 대해 헛소리를 내지 않습니다. 당신이 타당한 이유가 없다면, 균일성에 대한 최소한의 저항의 길을 택해서는 안됩니다. 나에게 순응을 설교하지 마십시오. 더 좋은 일이 있습니다.


6
일관성은 핵심이지만 정적으로 입력 된 언어와 최신 리팩토링 도구를 사용하면 이름을 변경하는 것이 쉽고 안전합니다. 따라서 첫 번째 개발자가 네이밍에서 잘못된 선택을 한 경우 영원히 함께 살 필요는 없습니다. 그러나 고유 한 코드베이스에서 이름을 변경할 수 있지만 프레임 워크 또는 타사 라이브러리에서는 이름을 변경할 수 없습니다. I- 접두사 (예 : 유사 여부)는 .net 세계에서 확립 된 규칙이므로 따르지 않는 것보다 규칙을 따르는 것이 좋습니다.
JacquesB

C #을 사용하는 경우 해당 IS가 표시됩니다. 코드에서 사용하면 어디서나 볼 수 있습니다. 코드에서 코드를 사용하지 않으면 프레임 워크 코드에서 해당 코드를 볼 수 있으므로 원하지 않는 믹스로 정확하게 연결됩니다.
Sebastian Redl

8

여기에 관련된 Java와 C # 사이에는 작은 차이가 있습니다. Java에서 모든 멤버는 기본적으로 가상입니다. C #에서는 인터페이스 멤버를 제외한 모든 멤버가 기본적으로 봉인됩니다.

이에 관한 가정은 지침에 영향을 미칩니다. Java에서는 모든 공개 유형이 Liskov의 대체 원칙 [1]에 따라 비 최종으로 간주되어야합니다. 구현이 하나 뿐인 경우 클래스 이름을 지정합니다 Parser. 여러 구현이 필요한 경우 클래스를 동일한 이름의 인터페이스로 변경하고 구체적인 구현의 이름을 설명으로 변경하면됩니다.

C #에서 주된 가정은 클래스를 가져올 때 (이름이로 시작되지 않음 I) 원하는 클래스라는 것입니다. 100 % 정확하지는 않습니다. 일반적인 카운터 예제는 Stream(실제로 인터페이스이거나 몇 개의 인터페이스 여야 했음) 같은 클래스가 될 것입니다. 모든 사람은 다른 언어의 고유 한 지침과 배경을 가지고 있습니다. Base추상 클래스를 나타 내기 위해 상당히 널리 사용되는 접미사 와 같은 다른 예외도 있습니다 . 인터페이스와 마찬가지로 유형이 다형성이어야한다는 것을 알고 있습니다.

또한 인터페이스를 추상 클래스로 만들지 않고 해당 인터페이스와 관련된 기능에 I 접두사가 아닌 이름을 남겨두면 유용한 유용성 기능이 있습니다 (C #의 클래스 다중 상속이 없기 때문에 상처를 입을 수 있음). LINQ IEnumerable<T>는 인터페이스와 Enumerable해당 인터페이스에 적용되는 메소드의 저장소로 사용됩니다. 인터페이스에는 메소드 구현도 포함될 수있는 Java에서는 필요하지 않습니다.

궁극적으로 I접두사는 C # 세계에서 널리 사용되며 확장으로 .NET 세계 (대부분의 .NET 코드는 C #으로 작성되므로 대부분의 공용 인터페이스에 대한 C # 지침을 따르는 것이 좋습니다)입니다. 이것은 거의 확실 하게이 표기법을 따르는 라이브러리 및 코드로 작업하고 있음을 의미하며 불필요한 혼란을 방지하기 위해 전통을 채택하는 것이 합리적입니다. 접두사를 생략하면 코드가 더 좋아질 것입니다 :)

밥 삼촌의 추론은 다음과 같다고 생각합니다.

IBanana바나나의 추상적 개념입니다. 보다 나은 이름을 가지지 않는 구현 클래스가있을 경우 Banana추상화는 전혀 의미 가 없으므로 인터페이스를 삭제하고 클래스를 사용해야합니다. 더 나은 이름 (예 : LongBanana또는 AppleBanana)이 있으면 Banana인터페이스 이름으로 사용하지 않을 이유가 없습니다 . 따라서 I접두사를 사용하면 쓸모없는 추상화가 생겨 코드를 이해하기 어렵게 만들 수 있습니다. 엄격한 OOP는 항상 인터페이스에 대해 코드를 작성 I하므로 유형 에서 접두사 가 표시되지 않는 유일한 위치 는 생성자에 있습니다.

이것을 샘플 IParser인터페이스에 적용 하면 추상화가 전적으로 "무의미한"영역에 있음을 분명히 알 수 있습니다. 어느 파서 (예를 들면의 구체적인 구현에 대한 구체적인 뭔가있다 JsonParser, XmlParser...), 아니면 그냥 클래스를 사용해야은. "기본 구현"과 같은 것은 없습니다 (일부 환경에서는 COM이 의미가 있습니다). 특정 구현이 있거나 "기본"에 대한 추상 클래스 또는 확장 메소드를 원합니다. 그러나 C #에서는 코드베이스에서 I-prefix를 이미 생략하지 않은 한 유지하십시오. 다음과 같은 코드를 볼 때마다 정신적으로 메모하십시오. class Something: ISomething누군가 YAGNI를 따르고 합리적인 추상화를 작성하는 데 능숙하지 않다는 것을 의미합니다.

[1]-기술적으로 이것은 Liskov의 논문에서 구체적으로 언급되지는 않았지만 원래 OOP 논문의 기초 중 하나이며 Liskov를 읽었을 때 그녀는 이것에 도전하지 않았습니다. 덜 엄격한 해석 (대부분의 OOP 언어가 사용하는 해석)에서, 대체 용 (예 : 최종 / 밀봉되지 않은) 공용 유형을 사용하는 코드는 해당 유형의 적합한 구현에서 작동해야합니다.


3
Nitpick : LSP는 모든 유형이 최종이 아니라고 말하지는 않습니다. 그것은 단지 형식에 대해 말한다 있습니다 final이 아닌, 소비자가 투명 서브 클래스를 사용할 수 있어야합니다. — 물론 Java에도 최종 유형이 있습니다.
Konrad Rudolph

@KonradRudolph 이에 관한 각주를 추가했습니다. 의견 주셔서 감사합니다 :)
Luaan

4

예를 들어이 두 가지의 이름은 무엇입니까? 파서와 콘크리트 파서? 파서 및 파서 구현?

이상적인 세상에서, 당신은 당신의 이름을 속기 ( "I ...")로 접두사로 붙이지 말고 단순히 이름이 개념을 표현하게하여야합니다.

이 ISomething 규칙을 사용하면 "Dollar"클래스가 필요할 때 "IDollar"개념을 정의 할 수 있다는 의견을 어디에서나 읽을 수 있지만 올바른 해결책은 단순히 "Currency"라는 개념 일 것입니다.

다시 말해,이 규칙은 사물의 이름을 지정하는 데 어려움을 겪기 쉽고 쉬운 것은 미묘한 잘못 입니다.


실제로는 코드의 클라이언트 ( "미래의 사용자"일 수 있음)는 나중에 코드를 읽고 가능한 한 빨리 (또는 적은 노력으로) 친숙해야합니다 (클라이언트에게 제공). 그들이 얻을 것으로 예상되는 코드).

ISomething 규칙은 cruft / bad 이름을 소개합니다. 즉, 코드 작성에 사용 된 규칙과 관행이 더 이상 실제가 아니라면 크래프트는 실제 크래프트가 아닙니다. 컨벤션에 "ISomething 사용"이라고 표시되어 있으면 다른 개발자와 일치하고 더 잘 작동하기 위해 컨벤션을 사용하는 것이 가장 좋습니다.


*) 나는 이것이 "부스러기"가 정확한 개념이 아니라고 말하면서 도망 갈 수있다 :)


2

다른 답변에서 언급했듯이 인터페이스 이름 앞에 접두사 I는 .NET 프레임 워크의 코딩 지침의 일부입니다. 구체적인 클래스는 C # 및 VB.NET의 일반 인터페이스보다 더 자주 상호 작용하기 때문에 명명 체계에서 일류 클래스이므로 IParser인터페이스와 Parser기본 구현에 가장 단순한 이름을 가져야합니다 .

그러나 구체적인 클래스 대신 인터페이스가 선호되는 Java 및 유사한 언어의 경우, Uncle Bob은 예를 들어 구문 분석기 인터페이스 I와 같이 인터페이스를 제거하고 인터페이스의 이름이 가장 단순해야한다는 점에서 옳습니다 Parser. 그러나 ParserDefault클래스 와 같은 역할 기반 이름 대신 파서의 구현 방식 을 설명 하는 이름이 클래스에 있어야합니다 .

public interface Parser{
}

public class RegexParser implements Parser {
    // parses using regular expressions
}

public class RecursiveParser implements Parser {
    // parses using a recursive call structure
}

public class MockParser implements Parser {
    // BSes the parsing methods so you can get your tests working
}

이 방법 예를 들어,이다 Set<T>, HashSet<T>그리고 TreeSet<T>이름이 지정됩니다.


5
C #에서도 인터페이스가 선호됩니다. 누구든지 닷넷에서 콘크리트 유형을 사용하는 것이 바람직하다고 말했습니까?
RubberDuck

@RubberDuck 언어가 당신에게 부과하는 몇 가지 가정에 숨겨져 있습니다. 예를 들어, 멤버가 sealed기본적으로 있다는 사실을 명시 적으로 만들어야합니다 virtual. C #에서 가상이되는 것은 특별한 경우입니다. 코드를 작성하기 위해 권장되는 방법은 수년에 걸쳐 변화로 물론, 과거의 많은 유물이 호환성을 유지하기 위해 필요한 :) 중요한 점은 (시작 C #에서 인터페이스를 얻는 경우이다 I), 당신이 알고 그것을 완전히이다 추상적 유형; 비 인터페이스를 얻는 경우 일반적인 가정은 그것이 원하는 유형이고 LSP가 손상되었다는 것입니다.
Luaan

1
@Luaan을 상속받을 수있는 상속인에 대해 명시 적으로 명시 하기 위해 멤버는 기본적으로 봉인되어 있습니다. 틀림없이 그것은 때때로 PITA이지만 구체적인 유형에 대한 선호와는 아무런 관련이 없습니다. 가상은 C #에서 특별한 경우가 아닙니다. 아마추어가 작성한 C # 코드베이스에서 작업하는 것이 불행한 것 같습니다. 언어에 대한 경험이 유감입니다. 개발자는 언어가 아니며 그 반대도 마찬가지입니다.
RubberDuck

@RubberDuck Hah, 나는 그것을 좋아하지 않는다고 결코 말하지 않았다. 대부분의 사람들이 간접 지식을 이해하지 못하기 때문에 나는 그것을 매우 선호한다 . 프로그래머들조차도. 기본적으로 봉인이 더 좋습니다 . 그리고 C #으로 시작했을 때 모든 사람들 이 .NET 팀을 포함한 아마추어였습니다. "실제 OOP"에서는 모든 것이 가상이어야합니다. 모든 유형은 파생 된 유형으로 대체 할 수 있어야합니다. . 그러나 "실제 OOP는"전문가를 위해 설계되었습니다, 그것은 :) 더 많은 돈을 위해 적은 작업이기 때문에 프로그래밍에 전구를 교체로 전환하지 명
Luaan

아니요. 아니요. "실제 OOP"는 전혀 작동하지 않습니다. Java에서는 오버라이드해서는 안되는 메소드를 봉인하는 데 시간이 걸리며 누구나 와일드 웨스트처럼 남길 수는 없습니다. LSP는 원하는 것을 무시할 수있는 것은 아닙니다. LSP는 한 클래스를 다른 클래스로 안전하게 대체 할 수 있음을 의미합니다. Smh
RubberDuck

-8

이 I = 인터페이스 규칙이 (새로운) 규칙을 위반한다는 것이 맞습니다.

옛날에는 intCounter boolFlag 등으로 모든 것을 접두어로 사용했습니다.

접두사없이 물건의 이름을 지정하고 'ConcreteParser'도 피하려면 네임 스페이스를 사용할 수 있습니다

namespace myapp.Interfaces
{
    public interface Parser {...
}


namespace myapp.Parsers
{
    public class Parser : myapp.Interfaces.Parser {...
}

11
새로운? 낡은? 잠깐, 나는 프로그래밍이 과대 광고보다 합리성에 관한 것이라고 생각했다. 아니면 옛날에 있었습니까?

3
컨벤션을 구성하고 그들이 어떻게 '가독성을 향상 시키는가'에 대한 블로그에 관한 모든 것
Ewan

8
나는 당신이 헝가리어 표기법을 생각하고 있다고 생각합니다. 그러나 당신이 intCounter또는 같은 것을 쓸 시간은 없었습니다 boolFlag. 그것들은 잘못된 "유형"입니다. 대신 pszName(이름을 포함하는 NUL로 끝나는 문자열의 포인터), cchName(문자열 "name"의 문자 수), xControl(제어의 x 좌표), fVisible(무엇이 보이는 것을 나타내는 플래그), pFile( 파일), hWindow(창 처리) 등이 있습니다.
코디 그레이

2
이것에는 여전히 많은 가치가 있습니다. 에 추가 xControl할 때 컴파일러에서 오류가 발생하지 않습니다 cchName. 둘 다 유형 int이지만 의미가 매우 다릅니다. 접두사는 이러한 시맨틱을 인간에게 분명하게 만듭니다. NUL 종료 문자열에 대한 포인터는 파스칼 스타일 문자열에 대한 컴파일러의 포인터와 똑같습니다. 마찬가지로 I인터페이스 의 접두사는 인터페이스가 실제로 클래스 인 C ++ 언어로 나타났습니다 (실제로 언어 수준의 클래스 또는 인터페이스와 같은 것이없는 C의 경우 모두 규칙 일뿐입니다).
코디 그레이

4
@CodyGray Joel Spolsky는 헝가리어 표기법과 그것이 잘못 이해 된 방식에 대해 잘못된 코드를 잘못 보이게 만드는 멋진 기사를 썼습니다 . 그는 접두사가 원시 데이터 스토리지 유형이 아닌 상위 레벨 유형이어야한다는 비슷한 견해를 가지고 있습니다. 그는 "종류"라는 단어를 사용합니다. " 시몬이가 실수로 그의 논문에서 단어 유형 을 사용했고, 여러 세대의 프로그래머들이 자신이 의미하는 바를 잘못 이해 했기 때문에 나는 의도적으로 단어 종류 를 사용하고 있습니다."
Joshua Taylor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.