인터페이스 이름은 "I"접두사로 시작해야합니까?


73

로버트 마틴이 " 깨끗한 코드 "를 읽고 더 나은 프로그래머가되기를 바랍니다. 지금까지 그 어느 것도 실제로 획기적인 것은 아니지만 응용 프로그램을 디자인하고 코드를 작성하는 방법에 대해 다르게 생각하게 만들었습니다.

이 책에는 동의하지 않을뿐만 아니라 특히 인터페이스 명명 규칙과 관련하여 이해가되지 않는 부분이 있습니다. 다음은 책에서 직접 가져온 텍스트입니다. 혼란스럽고 명확하게 설명하려는 측면을 굵게 표시했습니다.

인터페이스를 무인 상태로 두는 것을 선호합니다. 오늘날의 레거시 뭉치에서 흔히 볼 수있는 앞의 I는 최악의 경우 너무 혼란스럽고 너무 많은 정보입니다. 내 사용자가 인터페이스를 전달한다는 것을 알고 싶지 않습니다 .

아마도 학생 일뿐이거나 전문가 또는 팀 기반 프로그래밍을 한 적이 없기 때문에 사용자가 인터페이스임을 알기를 원할 것입니다. 인터페이스 구현과 클래스 확장에는 큰 차이가 있습니다.

그래서 제 질문 은 "코드의 일부가 인터페이스를 기대한다는 사실을 숨겨야하는 이유는 무엇입니까?"로 귀결됩니다.

편집하다

답변에 대한 답변 :

유형이 인터페이스이거나 클래스가 비즈니스 인 경우 코드를 사용하는 사람의 비즈니스가 아닙니다. 따라서이 타사 코드에서 코드의 세부 정보를 유출해서는 안됩니다.

주어진 유형이 인터페이스인지 또는 타사 코드에 대한 클래스인지에 대한 세부 정보를 "누설"해서는 안되는 이유는 무엇입니까? 인터페이스를 구현할지 또는 클래스를 확장할지 여부를 알기 위해 내 코드를 사용하는 타사 개발자에게 중요하지 않습니까? 차이점을 내가 생각하는 것만 큼 중요하지 않은가?


3
나는 당신의 요점에 동의합니다. 너무 많은 정보 숨기기가 그다지 도움이되지 않는 시점이 있습니다. 그러나이 지침을 준수하더라도 IDE 또는 애드온을 사용하여 유형을 알려줄 수 있습니다.
NoChance

3
이 질문은 본질적으로 "헝가리어 표기법"의 문제로 알려져 있으며, 많은 키워드와 대부분의 비 MS 개발자가이 키워드로이 질문을 포기한 이유를 찾아야합니다. 헝가리어 표기법은 변수에 주로 사용되지만 유형에 대해서는 본질적으로 동일합니다.
thiton

2
이전 타이틀 편집은 끔찍했습니다. 이 질문은 일반적으로 헝가리어 표기법에 관한 것이 아니며 단순히 관련 규칙을 언급하기 때문입니다. HN의 상대적인 장점은 여기에서 전적으로 무관합니다. 문제는 특별히 인터페이스 대 클래스와 의미 론적 차이가 특별한 경우 명명 규칙을 정당화하기에 충분히 중요하고 관심이 있는지 여부에 관한 것이 었습니다.
Aaronaught

Re to know whether they will be implementing an interface or extending a class: 예, 그러나 대부분의 코드 사용자는 코드를 호출하거나 구현하거나 확장하지 않으며 실제로 어떤 코드인지 신경 쓰지 못했습니다.
david.pfx

그만한 가치가 있기 때문에 나는 "I"접두사를 매우 선호합니다. 또한 같은 이유로 추상 클래스에 "Abstract"접두사를 사용합니다. 클래스 / 인터페이스 소비자에게는 차이가 없지만 인스턴스를 제공해야하는 사람들에게는 큰 차이를 만들 수 있으며 코드를 읽는 다른 개발자에게는 훨씬 더 단순 해집니다. 더 많은 정보를 위해 사례별로 IDE를 참조 할 필요없이, 그들이 다루고있는 것을 한눈에 볼 수 있음을 의미합니다. 방금 Angular를 사용하기 시작했으며 그들이이 규칙을 따르지 않는다는 것이 실제로 성가시다!
Dan King

답변:


66

그것에 대해 생각하지 않으면 인터페이스가 의미 상 추상 클래스와 크게 다르지 않다는 것을 알 수 있습니다.

  • 둘 다 메소드 및 / 또는 속성 (동작)을 가지고 있습니다.
  • 개인 필드가 아닌 필드 (데이터)가 없어야합니다.
  • 직접 인스턴스화 할 수도 없습니다.
  • 파생 된 유형도 추상적이 아닌 한 하나에서 파생한다는 것은 추상 메소드를 구현하는 것을 의미합니다.

실제로 클래스와 인터페이스의 가장 중요한 차이점은 다음과 같습니다.

  • 인터페이스는 개인 데이터를 가질 수 없습니다.
  • 인터페이스 멤버는 액세스 수정자를 가질 수 없습니다 (모든 멤버는 "공개"입니다).
  • 클래스는 일반적으로 하나의 기본 클래스에서만 상속 할 수있는 것이 아니라 여러 인터페이스를 구현할 수 있습니다.

클래스와 인터페이스 사이에서 특별히 의미있는 차이점은 (a) 개인 데이터와 (b) 유형 계층 구조와 관련이 있기 때문에 (호출자와는 조금도 차이가 없음) 일반적으로 유형이 인터페이스인지 또는 알 수 없는지 알 필요가 없습니다. 수업. 시각적 인 표시는 필요하지 않습니다 .

그러나 알아야 할 특정 경우가 있습니다. 특히, 리플렉션, 인터 셉션, 동적 프록시 / 믹싱, 바이트 코드 직조, 코드 생성 또는 환경의 타이핑 시스템 또는 코드 자체를 직접 엉망 으로 만드는 것을 사용하는 경우 매우 유용하며 때로는 즉시 알 필요가 있습니다. 인터페이스 또는 클래스를 다룰 때 박쥐. 인터페이스 대신 클래스를 믹스 인으로 추가하려고했기 때문에 코드가 신비하게 실패하는 것을 원하지 않습니다.

그러나 일반적인 바닐라 최고 수준의 비즈니스 로직 코드의 경우 추상 클래스와 인터페이스의 차이점을 알 필요가 없으므로 광고 할 필요가 없습니다.

이 모든 것이 말하지만, C # 인터페이스 접두어 I는 Microsoft가 사용하고 옹호하는 .NET 규칙이기 때문에 어쨌든 접두어 쓰는 경향이 있습니다. 그리고 새로운 개발자에게 코딩 규칙을 설명 할 때 왜 우리 자신의 "특별한"규칙을 갖는지 설명하는 것보다 Microsoft의 규칙을 사용하는 것이 훨씬 덜 번거 롭습니다.


이 고장에 감사드립니다. "클래스와 인터페이스의 의미있는 차이 ..."+1
Charles Sprayberry

23
+1 "이 모든 것은 말하지만 C # 인터페이스의 접두어는 Microsoft가 사용하고 옹호하는 .NET 규칙이기 때문에 어쨌든 접두어 붙는 경향이 있습니다." 이것이 C #에서 충분한 이유입니다. 이 공통 표준을 따르면 다른 .NET 프로그래머가 인터페이스를 식별 할 가능성이 높습니다.
로봇 스시

4
Java와 C #을 모두 작성하는 사람은 "이 모든 것이 말하지만, C # 인터페이스 앞에는 접두사를 붙인 경향이 있습니다. 왜냐하면 Microsoft에서 사용하고 옹호하는 .NET 규칙이기 때문입니다." 내가 어떤 언어로 일하고 있는지 기억하도록 도와줍니다.
Aidos

3
.NET (Java는 아님)의 또 다른 차이점은 많은 .NET 언어가 인터페이스에 정적 메소드를 포함 할 수 없기 때문에 인터페이스를 해킹하면 I클래스와 인터페이스와 관련된 정적 메소드를 보유 할 수있는 좋은 이름을 제공 할 수 있다는 것입니다 (예 : Enumerable<T>.Empty또는 Comparer<T>.Default).
supercat

한 가지 우려가 있습니다. C ++에서 헤더를 열고 class Foo이미 확장 되는 것을 class Bar확인하면 class Bar확장되거나 구현 되는지 여부 는 즉시 명확하지 않습니다 . 이제 class Bar헤더 로 이동 class Foo하여 extend 를 수정해도 괜찮은지를 결정해야합니다 class Baz. 또한 "단일 기본 클래스"를 위반했는지 여부에 관계없이 I 접두어를 통해 시각적 인 힌트를 얻을 수 있습니다. 따라서 헤더를 열 때마다 상태 점검을받을 수 있습니다.
jsj

14

여러면에서 일관성은 컨벤션보다 중요합니다. 이름 지정 체계가 일관된 한 작업하기가 어렵지 않습니다. 원하는 경우 I 접두사 인터페이스를 사용하거나 이름을 그대로두면 스타일을 선택하고 고수하는 한 나에게 중요하지 않습니다!


2
일관성> 규칙의 경우 +1 C #에서는 I 접두사를 사용하고 Java에서는 접두사를 사용하지 않습니다. 다른 임무는 다른 규칙을 요구합니다
Bringer128

2
+1 개인적으로 인터페이스에 Is를 사용하지 않는 것을 선호하지만 .Net 프로젝트에 사용되는 BCL 및 타사 라이브러리와 일치하지 않는 것은 옵션이 아닙니다.
jk.

13

이 책은 좋은 것들로 가득 차 있지만 여전히 인터페이스 이름에 "I"를 추가합니다.

public interface ILog기본 구현 이 있다고 상상해보십시오 public class Log.

자,를하기로 결정했다면 public interface Log갑자기 Log 클래스를 public class LogDefault그 라인의 것으로 변경해야합니다 . 당신은 하나의 추가 캐릭터를 7에서 7로 옮겼습니다.

이론과 실제 사이에는 종종 미세한 선이 있습니다. 이론적으로 이것은 정말 좋은 생각이지만 실제로는 좋지 않습니다.


이것은 또한 .NET 문서에
levininja

30
"기본 구현 공용 클래스 Log가있는 공용 인터페이스 ILog가 있다고 가정하십시오." 그런 다음 기본 구현에 대한 이름이 잘못되었습니다. 무엇을 Log합니까? 콘솔에 로그인 하시겠습니까? syslog에? 아무데도? 그것들은 각각 ConsoleLog, SyslogLog및 로 불려 져야합니다 NullLog. Log구체적인 이름이 아니기 때문에 구체적인 클래스에는 적합하지 않습니다.
Sebastian Redl

7
개인적으로 이것은 내가 ITheClassName을 보는 것을 싫어하는 이유입니다. 이유없이 인터페이스를 만들었습니까? TheClassName 위에 잡음이 있습니다. 인터페이스에 목적이 있다면 ITheClassName보다 더 나은 이름을 지정할 수 있어야합니다.
Richard Tingle

클래스 이름은 한 번 (인스턴스화하기 위해) 사용되며, 인터페이스 이름은 모든 곳에서 사용됩니다. 클래스 이름에 문자를 저장하기 위해 인터페이스에 문자를 추가하는 것은 (경제적 인) 잘못된 경제학입니다.
sergut

@RichardTingle하지만 그 때문에 일반적인 사용은 단순히 있다고 생각 MyClassmockable 변화를 오른쪽? 즉 우리는 종종 본질적으로 공개 방법을 만들기 위해 인터페이스를 사용한다 정말로 테스트 할 수있는 방식으로 공공. (즉, 좋거나 나쁜 말을하지만, 인터페이스에 대한 동기가 단순히 1 대 1 설명 않습니다 의존성이 쉽게 mockable있는 클래스를 만들기 위해 종종 것을 이해하지 MyClassIMyClass매핑합니다.)
러핀

8

이것은 인터페이스를 구현하거나 클래스를 확장하는 것이 아닙니다. 그런 경우에, 당신은 어쨌든 당신이하고있는 것을 알고 있습니다.

그러나 타사 코드 (예 : 응용 프로그램의 다른 모듈)가 데이터를 조작 할 때이 코드는 인터페이스 나 클래스를 제공하는지 상관하지 않습니다.

이것이 추상화의 요점입니다. 이 타사 코드에 지정된 유형의 객체를 제시하고 있습니다. 이 유형에는 호출 할 수있는 멤버 함수가 있습니다. 충분 해.

유형이 인터페이스이거나 클래스가 비즈니스 인 경우 코드를 사용하는 사람의 비즈니스가 아닙니다. 따라서 코드의 세부 정보를이 타사 코드로 유출해서는 안됩니다.

그런데 인터페이스와 클래스는 마지막에 참조 유형입니다. 그리고 이것이 중요합니다. 이것이 바로 네이밍 컨벤션이 강조해야 할 사항입니다.


@Mat> 예, 그건 내 실수였으며 편집했습니다.
deadalnix

5

대부분의 답변은 프로그래밍 언어가 인터페이스 또는 추상 클래스에 대한 개념 (또는 키워드)이있는 Java 또는 C #이라고 가정합니다. 이 경우 괜찮은 IDE에서는 어떤 유형의 클래스 1을 다루고 쓰기 public interface IMyClass가 불필요한 복제 인지 즉시 볼 수 있습니다 . 쓰지 않는 것과 같습니다. public final FinalMyClass모든 키워드를 클래스 이름에 넣는 것을 상상해보십시오.

그러나 C ++에 대한 필자의 의견으로는 헤더 파일로 뛰어 들어 클래스에 추상 클래스인지 확인하는 가상 메소드가 있는지 확인해야하므로 상황이 약간 다릅니다. 이 경우 글쓰기에 대한 논증을 분명히 볼 수 있습니다 class AbstractMyClass.

내 대답은 다음과 같습니다. 프로그래밍 언어에 따라 다릅니다.

2016 년 업데이트 : 2 년의 C ++ 경험 나중에 클래스 이름 앞에 접두사를 붙이는 것은 나쁜 습관 Abstract이라고 생각할 것입니다.


이것이 질문에 대한 답입니까? 다른 답변을 읽고 요점을 명확히하고 싶을 수도 있습니다.
david.pfx

C ++에는 키워드가 없더라도 인터페이스가 있습니다. 모든 멤버 함수가 순수 가상이고 멤버 변수가없는 클래스를 무엇이라고 부릅니까?

@ david.pfx : "인터페이스 이름이"I "접두사로 시작해야합니까?"라는 질문에 정확하게 대답한다고 생각합니다. 프로그래밍 언어에 따라 다릅니다. 내 정교함이 충분히 명확하지 않다고 생각되면 개선해 드리겠습니다. 어떤 부분이 명확하지 않습니까?
Ela782

2
@ JohnGaughan : 물론 인터페이스가 있습니다! 그러나 내 요점은 키워드에 관한 것 입니다 . C ++에는 인터페이스 가 없으므로 IDE / 사용자가 인터페이스를 처리하는지 여부를 표시하지 않습니다. 그러나 Java에서는 즉시 볼 수 있습니다.
Ela782

1
최고 등급의 답변을 읽고 귀하의 답변을 비교하십시오. 당신은 SO를 처음 사용하며, 이것은 어떤 종류의 답변이 투표에 끌리는지를 배울 수있는 기회입니다. 그대로, 당신은하지 않습니다. 더 많은 일, 더 많은 설명, 더 많은 가치를 가진 것만으로도 가능합니다. 잠깐만!
david.pfx

4

사용중인 언어의 관용구를 따르십시오.

각 언어에는 고유 한 관용구 및 코딩 지침이 있습니다. 예를 들어, C #에서는 인터페이스 접두어를 I로 지정하는 것이 관용적입니다. Go에서는 그렇지 않습니다.


+1 사용하는 언어의 관용구를 따르십시오. 분명히 책 저자는 Java 개발자입니다. .NET / C # : ILog Java : Log 그러나 단점 : ILog 인터페이스를 구현하는 Log 클래스가 필요할 때 .... MyLog, LogDefault, LogBase, ...? 못 생겼어? 더 못생긴 : LogImpl .... : D
hfrmobile

0

내 (자바) 코드에서 호출자에게 노출되는 API 에이 규칙을 사용하는 경향이 있습니다.

  • 기능은 인터페이스를 통해 제공 되며 클래스 에서는 제공 되지 않습니다 .
  • 작동하지 않는 부품은 클래스입니다.

비 기능, 나는, 모두 열거 및 예외 (예 : XML 직렬화 또는 ORM에 다리 역할을 클래스 등) 순수 데이터 구조 같은 것들을 의미 할 수없는 인터페이스 수를 (물론, 당신이 할 수있는 순수한 데이터 클래스에 대한 그러나 클래스가 데이터를 보유 하는 것 외에는 아무것도 없기 때문에 약간의 이익을 얻으려면 많은 작업이 필요 합니다).

명명 규칙과 관련하여 인터페이스는 액터 명사 (예 :) FooBarWatcher또는 형용사 (예 :)에 매핑되는 경향이 FooBarWatchable있으며 순수한 데이터 클래스와 열거는 모두 비 활동 명사 (예 :)에 매핑됩니다 FooBarStatus. IDE는 특별한 명명 규칙없이 API 소비자를 안내 할 수 있습니다. 예외는 일반적인 자바 규칙 (따라 FooBarException, FooBarError, FooBarFault물론)를.

또한 종종 내 규칙을 어 기고 싶은 유혹을받지 않기 위해 자체 패키지 나 라이브러리에 인터페이스를 배치하기도합니다. 또한 WSDL 문서와 같은 외부 소스에서 코드를 가져올 때 빌드를 관리하는 데 도움이됩니다.


또한 I인터페이스 에 접두사를 두지 않습니다 . 의 과정 은 인터페이스입니다! API (또는 SPI)에 있습니다!
Donal Fellows
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.