Java에서 인터페이스 이름 지정


324

대부분의 OO 언어는 인터페이스 이름 앞에 대문자 I를 붙입니다. Java가 왜 그렇게하지 않습니까? 이 협약을 따르지 않은 이유는 무엇입니까?

의미하는 바를 보여주기 위해 사용자 인터페이스와 사용자 구현을 원한다면 Java에서 두 가지 선택이 있습니다.

  1. 클래스 = 사용자, 인터페이스 = UserInterface
  2. 클래스 = UserImpl, 인터페이스 = 사용자

대부분의 언어로 :

클래스 = 사용자, 인터페이스 = IUser

이제는 항상 사용자 구현을 위해 가장 설명적인 이름을 선택할 수 있다고 주장 할 수 있지만 문제는 사라지지만 Java는 POJO 접근 방식을 추진하고 대부분의 IOC 컨테이너는 DynamicProxies를 광범위하게 사용합니다. 이 두 가지를 함께 사용하면 단일 POJO 구현으로 많은 인터페이스를 사용할 수 있습니다.

그래서 제 질문 은 "자바 프레임 워크가 어디로 향하고 있는가에 비추어보다 광범위한 인터페이스 명명 규칙을 따를 가치가 있습니까?"


61
"대부분의 언어로 어디에"? .Net 이외의 언어는 무엇입니까?
wds

2
언어 커뮤니티마다 다른 이름 지정 규칙이 있으며 이는 오랜 기간 동안 사실이었습니다. 명명 규칙이 어떻게 시작되었는지 알아내는 것은 때때로 민속 연구입니다.
David Thornley

4
Eclipse는 IFoo 스타일 명명과 함께 Java를 사용하는 중요한 이상치입니다. wiki.eclipse.org/Naming_Conventions
David Leonard

2
당신이 (물론 자바를) 안드로이드 SDK의 인터페이스의 이름을 보는 경우에, 당신은 그들이 인터페이스 이름의 끝에 같은 단어 인터페이스를 가진의 규칙을 사용하는 것을 볼 NetworkInterface, DialogInterface
sandalone

21
이 질문이 많은 사람들에게 인기가 있고 관심이있을 때 어떻게 "건설적이지 않은 것으로 폐쇄"될 수 있습니까?
inor

답변:


329

인터페이스에 접두사를 사용하지 않는 것이 좋습니다.

  • 접두사는 가독성을 떨어 뜨립니다.

  • 클라이언트에서 인터페이스를 사용하는 것이 가장 좋은 프로그래밍 방법이므로 인터페이스 이름은 가능한 짧고 유쾌해야합니다. 클래스 사용을 권장하지 않기 위해 클래스를 구현하는 것이 더 어려워 야합니다.

  • 추상 클래스에서 인터페이스로 변경할 때 접두사 I이있는 코딩 규칙은 클래스의 모든 항목 이름을 바꾸는 것을 의미합니다.


12
전적으로 동의합니다. 자동 완성을 사용하는 경우 입력 할 키가 하나 더 있습니다. I로 시작하는 많은 파일들
Kalecser

85
괜찮은 IDE를 사용하면 쉽게 설명하는 방식으로 코드를 변경할 수 있습니다. 또한 추상 클래스에서 인터페이스로 변경할 때 클라이언트가 어쨌든 다시 컴파일해야한다고 확신합니다.
Allain Lalonde

63
슈퍼 늦게 여기지만 : 그것은 중요하지 않습니다 전혀 IDE를 쉽게 무언가의 이름을 변경하게합니다. 어떤 유형의 인스턴스를 사용하는 코드는 그 유형이 인터페이스인지 클래스인지 또는 무엇인지 신경 쓰지 않아야합니다. 따라서 유형의 이름으로 이러한 세부 사항을 노출하는 것은 의미가 없으며 이해에 해 롭습니다. 노출되는 유형과 계약이 중요합니다!
ColinD

11
또한 IFoo의 경로를 가고 있다면 구현을위한 CFoo가 아니어야하며 물론 실패 할 경우 메서드가 EFoo를 던질 수 있습니다.
Robin

57
"접두사는 가독성을 떨어 뜨립니다"는 순전히 주관적입니다. 대부분의 명명 규칙과 마찬가지로. 코드 기반이 일관되도록 팀이해야 할 일에 대한 합의에 따라 팀을 구성하는 것이 더 중요합니다.
dreadwail

121

실제로 다음과 같은 차이점이 있습니까?

class User implements IUser

class UserImpl implements User

우리가 말하는 전부가 명명 규칙일까요?

개인적으로 인터페이스에 I코딩하고 싶을 때 인터페이스보다 우선하지 않으며 이름 지정 규칙 측면에서 더 중요하다고 생각 합니다 . 인터페이스 IUser를 호출하면 해당 클래스의 모든 소비자 는 인터페이스 를 알아야합니다 IUser. 클래스 UserImpl를 호출하면 클래스 와 DI 컨테이너 만 Impl파트 에 대해 알고 소비자는 자신이 작업하고 있음을 알 수 User있습니다.

그런 다음, Impl더 나은 이름이 없기 때문에 사용하도록 강요된 시간은 그 구현이 구현 에 따라 이름이 지정되기 때문에 그 사이 가 중요하지 않습니다. 예를 들어

class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO

클래스를 열 필요없이 일반적인 기능을 설명하기 때문에 DAO를 알고 싶습니다. 프로젝트에서 클래스 파일을 살펴보면 * DAO를 검색하여 모든 DAO를 쉽게 볼 수 있습니다.
Patrick

6
DAO는 데이터베이스 액세스를위한 잘 알려진 패턴이므로, 이름에 패턴이 있으면 이름을보고 클래스의 기능을 쉽게 알 수 있습니다. PS 엄격하게 낙타 표기법에 따라 같은에서와 같이 ( "AccountDao") 더 좋을 것 mina.apache.org/changes-between-2x-and-1x.html
에스코 Luontola

4
@ 마커, 인터페이스를 나타내는 I를 갖는 것과는 다릅니다. DAO는 클래스 또는 인터페이스가 계정 데이터에 액세스하기위한 개체이며 개체가 수행하는 것임을 알려줍니다. I가 있으면 인터페이스 자체만으로도 객체 자체와는 아무 관련이 없으며 언어의 의미와 관련이 있습니다
tddmonkey

당신이 그것을 제시 할 때 접두사 대 접두사.
Andrei Rînea

3
@Andrei : 아니요, 의미론 ( "DAO") 대 언어 아티팩트의 불필요한 장식 (인터페이스에서와 같이 "I"; 코드에서 언급 된 사실은 "인터페이스 IFoo ...")
Dirk

75

Java가 일반적으로 IUser 규칙을 사용하지 않는 몇 가지 이유가있을 수 있습니다.

  1. 객체 지향 접근 방식의 일부는 클라이언트가 인터페이스 또는 구현 클래스를 사용하는지 여부를 알 필요가 없다는 것입니다. 따라서 List조차도 인터페이스이고 String은 실제 클래스이므로 메소드가 둘 다 전달 될 수 있습니다. 인터페이스를 시각적으로 구별하는 것은 의미가 없습니다.

  2. 일반적으로 클라이언트 코드에서 인터페이스 사용을 선호합니다 (예 : List를 ArrayList보다 선호). 따라서 인터페이스를 예외로 눈에 띄게 만드는 것은 의미가 없습니다.

  3. Java 이름 지정 규칙은 헝가리어 스타일 접두어보다 실제 의미가있는 더 긴 이름을 선호합니다. 따라서 코드는 가능한 한 읽기 쉽습니다. List는 목록을 나타내고 User는 IUser가 아닌 사용자를 나타냅니다.


72

Spring을 포함한 많은 오픈 소스 프로젝트에서 사용되는 또 다른 규칙이 있습니다.

interface User {
}

class DefaultUser implements User {
}

class AnotherClassOfUser implements User {
}

나는 개인적으로 "I"접두어가 선택적인 규칙이라는 단순한 이유 때문에 마음에 들지 않습니다. 그래서 이것을 채택하면 IIOPConnection은 IOPConnection의 인터페이스를 의미합니까? 클래스에 "I"접두사가없는 경우 어떻게해야 인터페이스가 아닌지 알 수 있습니다. 규칙이 항상 준수되는 것은 아니기 때문에 여기에 대한 대답은 '아니오'입니다.


클래스를 연결하는 대신 외부 종속성에 대한 인터페이스를 사용하는 모드에서 도움을주기 때문에 이것을 좋아합니다.
매트 브릭스

47

다른 포스터가 말했듯이 인터페이스가 유형이 아닌 기능을 정의하도록하는 것이 일반적으로 바람직합니다. 나는 "사용자"와 같은 것을 "구현"하지 않는 경향이 있으며, 이것이 여기에 설명 된 방식으로 "IUser"가 실제로 필요하지 않은 이유입니다. 나는 종종 클래스를 명사로, 인터페이스를 형용사로 본다.

class Number implements Comparable{...}  
class MyThread implements Runnable{...}
class SessionData implements Serializable{....}

때때로 형용사는 이해가되지 않지만, 일반적으로 유형이 아닌 동작, 동작, 기능, 속성 등을 모델링하기 위해 인터페이스를 사용하고 있습니다.

또한 실제로 하나의 사용자를 만들고 사용자라고 할 경우 IUser 인터페이스도 갖는 요점은 무엇입니까? 공통 인터페이스를 구현해야하는 몇 가지 다른 유형의 사용자가있는 경우 인터페이스에 "I"를 추가하면 구현 이름을 선택하는 데 무엇이 도움이됩니까?

더 현실적인 예는 일부 유형의 사용자가 특정 API에 로그인 할 수 있어야한다고 생각합니다. Login 인터페이스를 정의한 다음 SuperUser, DefaultUser, AdminUser, AdministrativeContact 등의 suclass를 가진 "User"상위 클래스를 가질 수 있습니다.이 중 일부는 필요에 따라 Login (로그인 가능?) 인터페이스를 구현하거나 구현하지 않습니다.


"인터페이스로서의 인터페이스"를 지원하기 위해 제공 한 예제가 왜곡되어 있다고 생각합니다. 인터페이스는 믹스 인 (또는 특성)과 비슷하기 때문입니다. 따라서 인터페이스는 형용사와 명사 모두에 좋지만 indefinite transitive verbs 8 ^ P 에는 적합하지 않습니다.
Stevel

이것은 지난 몇 년 동안 변경되었을 수 있습니다. 오라클 문서. 허용 유형과 같은 인터페이스 [링크] docs.oracle.com/javase/tutorial/java/IandI/interfaceAsType.html
karlihnos

38

Bob Lee는 프레젠테이션에서 한 번 말했다.

구현이 하나 뿐인 경우 인터페이스의 요점은 무엇입니까?

따라서 인터페이스없이 하나의 구현으로 시작합니다. 나중에 여기에 인터페이스가 필요하다고 판단하므로 클래스를 인터페이스로 변환하십시오.

그러면 분명해집니다. 원래 클래스는 User라고 불 렸습니다. 인터페이스는 이제 사용자라고합니다. 어쩌면 UserProdImpl과 UserTestImpl이있을 수 있습니다. 응용 프로그램을 제대로 디자인하면 모든 클래스 (User를 인스턴스화하는 클래스 제외)는 변경되지 않으며 갑자기 인터페이스를 전달받지 않습니다.

그래서 그것은 명확 해집니다-> 인터페이스 사용자 구현 UserImpl.


18
인터페이스를 사용하면 개발 주도 테스트에 도움이됩니다. 인터페이스를 사용하지 않기로 결정했기 때문에 도메인 모델 및 테스트와 관련하여 수많은 문제가 발생했습니다. 내 친구가 한 번 인용했다. "모든 것이 인터페이스이므로 장기적으로 절약 할 수 있습니다."
hooknc

4
조롱과 쉬운 프록시 지원. 인터페이스를 제공 해야하는 다른 이유가 있다고 확신합니다.
MetroidFan2002

3
최근에 동료에게 말했듯이 지금 인터페이스를 도입하는 데 비용이 들지 않지만 나중에 많은 시간을 절약 할 수 있습니다.
tddmonkey

2
가까운 시일 내에 다른 구현이있을 경우 인터페이스가 유리할 것입니다.
Stef

3
나는 "나중에 또 다른 임프가 필요할지도 모른다"는 주장을 좋아하지 않는다. 나는 YAGNI 접근 방식을 선호합니다. 아직 일어나지 않은 것을 계획하지 마십시오.
David Lavender

24

C #에서는

public class AdminForumUser : UserBase, IUser

자바는 말할 것이다

public class AdminForumUser extends User implements ForumUserInterface

그 때문에 상속과 인터페이스 구현 사이에 명백한 차이가 있기 때문에 Java에서 인터페이스에 대한 규칙이 거의 중요하지 않다고 생각합니다. 나는 당신이 구성하고 사람들에게 인터페이스라는 것을 보여주기 위해 무언가를 사용하는 한 원하는 명명 규칙을 선택한다고 말하고 싶습니다. 몇 년 동안 자바를 해보지 않았지만 모든 인터페이스는 자체 디렉토리에있을 것입니다. 실제로 아무런 문제가 없었습니다.


22
어쩌면 나는 자바 코더가 좋지 않지만 C # 스타일을 선호합니다. 모든 인터페이스는 'I'접두사로 시작합니다 :)
davs

7
나는 당신과 다른 사람들이 어디 에서이 컨벤션을 받고 있는지 잘 모르겠습니다. Java 라이브러리에서는 분명하지 않습니다 ...
ChiefTwoPencils

6

내 경험상 "I"규칙은 특히 인터페이스 자체가 클래스의 추상적 인 개념이 아닌 경우 클래스에 대한 계약을 제공하려는 인터페이스에 적용됩니다.

예를 들어, 귀하의 경우, 유일 IUser하게 보유하려는 유일한 사용자가입니다 User. 당신은 다양한 유형의 사용자를 가질 계획이라면 - NoviceUser, ExpertUser등 - 나는 보여야하는데 User(아마도를 사용하며 인터페이스 AbstractUser가 구현하는 몇 가지 일반적인 기능, 같은 클래스 get/setName()).

나는 또한 기능을 정의하는 인터페이스를 기대 - Comparable, Iterable등 - 그런 이름이 아닌 같은 수 IComparable또는 IIterable.


유일하게 원하는 사용자가 사용자 인 경우 인터페이스 대신 사용자를 사용하는 것이 어떻습니까?
Carighan

3
일부 클라이언트 / 서버 아키텍처에서 클라이언트 측은 헤비급 서버 구현없이 인터페이스를 알아야합니다.
David Koelle

5

좋은 OO 원칙에 따라 코드는 (실용적이고 가능한 한) 구체적인 클래스가 아닌 추상화에 의존해야합니다. 예를 들어, 일반적으로 다음과 같은 메소드를 작성하는 것이 좋습니다.

public void doSomething(Collection someStuff) {
    ...
}

이것보다:

public void doSomething(Vector someStuff) {
    ...
}

이 아이디어를 따르는 경우 "IUser", "UserInterface"또는 기타 변형이 아닌 "User"및 "BankAccount"(예 :)와 같은 인터페이스 이름을 지정하면 코드를 더 읽기 쉽게 유지할 수 있습니다.

실제 구체적인 클래스에 신경을 써야하는 코드는 콘크리트 클래스가 생성되는 장소입니다. 다른 모든 것은 인터페이스를 사용하여 작성해야합니다.

이렇게하면 "UserImpl"과 같은 "추악한"구체적인 클래스 이름이 나머지 코드에서 안전하게 숨겨져 야합니다. "nice"인터페이스 이름을 사용하면됩니다.


그러나 하나 또는 두 가지에 대한 인터페이스 만 필요할 때 프로그램의 모든 클래스에 맞는 인터페이스를 만드는 것이 왜 귀찮습니까?
LegendLength

3

= v = "I"접두사는 Wicket 프레임 워크에서도 사용되는데, 여기서 빠르게 익숙해졌습니다. 일반적으로 성가신 Java 클래스 이름을 단축하는 규칙을 환영합니다. 그러나 디렉토리와 Javadoc에서 "I"로 모든 문자가 알파벳순으로 표시되어있어 번거 롭습니다.

Wicket 코딩 방법은 많은 컨트롤 / 위젯 인스턴스가 인라인 메서드 선언을 사용하는 익명 내부 클래스로 구성되어 있다는 점에서 Swing과 유사합니다. 짜증나게도 Swing은 구현 클래스에 접두사 ( "J")를 사용한다는 점에서 Swing과 180 °가 다릅니다.

"Impl"접미사는 맹렬한 약어이며 국제화가 잘되지 않습니다. 만약 우리가 최소한 "Imp"로 간다면 그것은 더 짧을 것입니다. "Impl"은 IOC, 특히 Spring에 사용되므로 지금은이 유형에 붙어 있습니다. 그러나 하나의 코드베이스의 세 가지 다른 부분에서 세 가지 다른 규칙에 따라 약간의 정신 분열을 얻습니다.


0

이것은 실제 의미에서 더 광범위한 명명 규칙입니까? 나는 C ++ 측면에 더 많이 있지만 실제로 Java와 자손에 대해서는 아닙니다. I 규칙을 사용하는 언어 커뮤니티는 몇 명입니까?

언어 독립적 상점 표준 명명 규칙이있는 경우이를 사용하십시오. 그렇지 않은 경우 언어 명명 규칙을 따르십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.