Java로 인터페이스를 구현할 때 기본 대 Impl


34

읽은 후 패키지 이름이 단수 또는 복수 여야합니까? 내 애완 동물 친구들 중 하나를 다루는 적절한 토론을 보지 못했습니다. 인터페이스 구현 이름 지정.

Order다양한 방법으로 구현하기위한 인터페이스 가 있지만 프로젝트를 처음 만들 때 초기 구현 만 있다고 가정 해 봅시다 . 당신은 갈 마십시오 DefaultOrder하거나 OrderImpl또는 잘못된 이분법을 피하기 위해 다른 변종? 그리고 더 많은 구현이 나오면 어떻게해야합니까?

그리고 가장 중요한 ... 왜?

답변:


59

이름은 의미를 전달할 기회가 있습니다. 왜 Impl과 함께 그 기회를 버리겠습니까?

우선, 구현이 하나 뿐인 경우 인터페이스를 사용하지 마십시오. 이 명명 문제를 만들고 아무것도 추가하지 않습니다. 더 나쁜 것은 사용자와 다른 모든 개발자가 항상 인터페이스 만 사용하도록주의하지 않으면 API에서 일치하지 않는 메소드 서명에 문제가 발생할 수 있습니다.

주어진 모든 인터페이스 두 개 이상의 구현을 거나 가질 수 있다고 가정 할 수 있습니다 .

  • 지금 하나만 가지고 있고 다른 방법이 어떻게 다른지 모르는 경우 기본을 시작하는 것이 좋습니다.

  • 지금 두 가지가 있다면 목적에 따라 각각 이름을 지정하십시오.

    예 : 최근에 우리는 구체적인 클래스 Context (데이터베이스를 참조)를 가졌습니다 . 오프라인 상태 인 컨텍스트를 표현할 수 있어야했기 때문에 Context라는 이름이 새 인터페이스에 사용되었으며 (이전 API와의 호환성을 유지하기 위해) 새로운 구현 인 OfflineContext 가 작성되었습니다 . 그러나 원본 이름이 무엇으로 바뀌었을까요? 맞습니다, ContextImpl (이크).

    이 경우 DefaultContext 는 괜찮을 것이고 사람들은 그것을 얻을 수 있지만 가능한 한 설명 적이지는 않습니다. 결국 오프라인아닌 경우 무엇입니까? 그래서 우리는 OnlineContext 와 함께 갔다 .


특수 사례 : 인터페이스에서 "I"접두사 사용

다른 답변 중 하나는 인터페이스에서 I 접두사를 사용하는 것이 좋습니다. 바람직하게는이 작업을 수행 할 필요 가 없습니다 .

그러나 사용자 정의 구현을 위해 인터페이스가 모두 필요하지만 자주 사용되는 기본 구현 이 있으며 기본 이름이 너무 단순하여 인터페이스 만 포기하면 추가를 고려할 수 있습니다. 인터페이스에 대한 "I"(여전히 당신과 당신의 팀에 맞지 않으면 괜찮습니다).

예 : 많은 객체가 "EventDispatcher"일 수 있습니다. API를 위해서는 인터페이스를 준수해야합니다. 그러나 위임을위한 기본 이벤트 디스패처도 제공하려고합니다 . DefaultEventDispatcher은 잘 될 것이다, 그러나 그것은 긴 조금, 그리고 당신이 자주의 이름을 볼 수있을 위하여려고하는 경우에, 당신은 수있는 기본 이름을 사용하는 것을 선호 하는 EventDispatcher를 콘크리트 클래스 및 구현 하여 IEventDispatcher를 사용자 정의 구현을 위해 :

/* Option 1, traditional verbose naming: */
interface EventDispatcher { /* interface for all event dispatchers */ }
class DefaultEventDispatcher implements EventDispatcher {
  /* default event dispatcher */
}

/* Option 2, "I" abbreviation because "EventDispatcher" will be a common default: */
interface IEventDispatcher { /* interface for all event dispatchers */ }
class EventDispatcher implements IEventDispatcher {
  /* default event dispatcher. */
}

3
확실한 대답을 위해 +1. Impl을 사용하지 않는 이유와 같습니다.
게리 로우

2
+1 절대적으로 동의합니다. 인터페이스가 나타내는 도메인 개념에서 벗어나 인터페이스 이름을 지정하는 것은 전혀 요점이 없습니다.
rupjones

9
"구현이 하나 뿐인 경우", 구현이 하나만 있다는 것을 미리 어떻게 알 수 있습니까? "모든 인터페이스에는 두 개 이상의 구현이 있거나있을 수 있습니다."... 두 개의 구현을하기 전에 먼저 아무것도없고, 하나가 있고, 두 개가 있습니다. 구현이 하나 뿐인 순간이있을 수 있습니다. 두 번째 것을 구현하기 전에.
Tulains Córdova

2
@ NickC 나는 시맨틱에 대해 pedantinc가 아닙니다 (나는 시인이며 그것을조차 몰랐습니다). 영어는 모국어가 아니기 때문에 그것에 대해 농담을 할 수 없습니다. 나는 결함이있는 논리에 대해 이야기하고 있었다. 디커플링에 인터페이스를 사용합니다. 특정 수의 구현이 필요하지 않습니다.
Tulains Córdova

4
if you will only ever have one implementation, do away with the interface-구성 요소를 테스트하고 싶지 않은 경우 MockOrder, OrderStub 또는 이와 유사한 것을 만들기 위해 해당 인터페이스를 유지하려는 경우가 있습니다.
JBR 윌킨슨

15

인터페이스의 유스 케이스로 명명을 결정합니다.

인터페이스가 디커플링에 사용되는 경우 Impl구현을 선택 합니다.

인터페이스의 목적이 행동 추상화 인 경우, 구현은 구체적으로 수행하는 작업에 따라 이름이 지정됩니다. 나는 종종 인터페이스 이름을 추가합니다. 따라서 인터페이스가 호출 Validator되면을 사용 FooValidator합니다.

나는 그것이 Default매우 나쁜 선택 이라는 것을 알았습니다 . 먼저 이름이 항상 그것으로 시작하기 때문에 코드 완성 기능을 오염시킵니다. 다른 것은 기본값은 시간이 지남에 따라 변경 될 수 있다는 것입니다. 따라서 기본값이 될 수있는 것은 더 이상 사용되지 않는 기능 일 수 있습니다. 따라서 기본값이 변경되는 즉시 클래스 이름을 바꾸거나 잘못된 이름으로 생활하기 시작합니다.


8

나는 (인터페이스가 아마 대부분의 경우에 필요하지 않습니다 특히 있음)하지만, 토론을 위해 내가 추가로 다른 대안에 비해 밖으로 던질거야 니콜의 답변에 동의 OrderImpl하고 DefaultOrder숨기기 같은 정적 팩토리 메소드 뒤에 구현을 :에게 Orders.create(). 예를 들면 다음과 같습니다.

public final class Orders {
  public static Order create() {
    return new Order() {
      // Implementation goes here.
    };
  }
}

이 방법을 사용하면 구현이 익명의 내부 클래스이거나 이름이 있거나 이름 이있는 개인 클래스 Default이거나 Impl완전히 다른 이름이 될 수 있습니다. 어느 쪽을 선택하든 발신자는 신경 쓸 필요가 없으므로 변경하기로 결정한 시점과 시점에 더 많은 유연성을 얻을 수 있습니다.

실제로이 패턴의 좋은 예는 java.util.Collectionsand java.util.concurrent.Executors유틸리티 클래스이며,이 클래스의 메서드는 숨겨진 구현을 반환합니다. Effective Java에서 언급 한 것처럼 (항목 1)이 패턴은 API의 "개념적 가중치"를 작게 유지하는 데 도움이됩니다.


흥미로운 추가 사례 : +1 : 익명 구현
Gary Rowe

1
구아바 에서도 광범위하게 사용됩니다 .
Nicole

3

인터페이스 OrderImpl바로 뒤에 알파벳순으로 표시되기 때문에 항상 간단하게 진행합니다 Order.


2
그리고 특수 처리 등을 위해 진행중인 추가 구현을 어떻게 처리합니까?
게리 로우

1
초기 구현에 대해 물었습니다. DomesticOrder, ForeignOrder 등을 구현하기 시작하면 알파벳에서의 위치와 관계없이 더 신중하게 이름이 지정됩니다.
벤 호프 슈타인

아주 그렇습니다-이 새로운 요구 사항을 반영하기 위해 원래 질문을 편집했습니다.
게리 로우

좋은 생각은 아닙니다. 하나 이상의 구현이있을 경우.
Sadegh

0

접두사 I (IWhatever)로 인터페이스의 이름을 지정한 다음 Whatever를 구현할 수 있습니다.

공식 Java 코드 규칙은 이러한 종류의 인터페이스 이름 지정에 대해 설명하지 않지만 이러한 종류의 이름 지정은 인식 및 탐색에 도움이됩니다.


왜 인터페이스 앞에 I를 붙이겠습니까? 내비게이션에서 인식하는 데 도움이됩니까?
게리 로우

@Gary : I로 접두사 인터페이스 유형은 Delphi 언어에서 잘 확립 된 규칙입니다. 델파이 클래스 타입은 T로 시작합니다. 그래서 우리는 IOrder 인터페이스와 TSomethingOrder와 TBullMarketOrder를 특정 구현으로 사용하는 TOrder 기본 구현을 갖습니다.
Marjan Venema

3
이 규칙은 .NET 개발에서도 많이 사용되는 것을 보았습니다. 아마도 Microsoft의 문서와 예제에서 사용하기 때문일 것입니다.
벤 호프 슈타인

5
@Renesis는 Java 내에서 사용하기에 유용한 사례를 제시 한 것으로 보입니다. 개인적으로, 나는 IDE에 의존하여 다른 점을 말해주었습니다. 그렇지 않으면 E 's for Enums, C 's for classs 및 크게 중복되는 차이점이 있습니다.
게리 로우

0

기본적으로 Default가 의미가 있지만 구현을 설명하는 것이 더 도움이 될 것이라고 생각합니다. 사용자 인터페이스는 그래서 만약 UserProfileDAO다음 구현 될 수있다 UserProfileSQLDAO거나 UserProfileLDAPDAO또는 그런 일.


0

가능하다면 무엇을 / 어떻게하는지에 따라 이름을 지정하십시오.

일반적으로 최악의 접근 방식은 사용 방법에 따라 이름을 지정하는 것입니다.

구현을위한 기본 클래스로 사용되어야하는 경우 BaseX 또는 AbstractX를 사용할 수 있습니다 (추상적 인 경우 (그러나 그것이 수행하는 작업을 짜지 마십시오. 가능한 가장 간단한 기능을 제공하고 그러한 기능이 충분할 때 직접 사용하지 않을 것으로 예상되는 경우 SimpleX 또는 BasicX라고 부를 수 있습니다.

다른 구현이 제공되지 않는 한 사용되는 경우 이름을 DefaultX로 지정하십시오.


-2

이 답변의 대부분은 수행되고 있지만 왜 그런지 설명하지 않습니다.

OO 원칙은 어떻게 되었습니까? Impl은 수업에 대해 무엇을 말하고 어떻게 사용합니까? 사용법을 구성하는 방법이 아니라 사용법을 이해해야합니다.

Person 인터페이스를 만들면 PersonImpl이란 무엇입니까? 무의미한. 최소한 DefaultPerson은 인터페이스를 작성해서는 안되는 코드를 작성한 사람에게 알려줍니다.

인터페이스는 다형성을 위해 타이핑하고 있으므로 그대로 사용해야합니다.


1
@NickC에서 받아 들여진 대답은 수행중인 작업과 이유에 대해 자세히 설명합니다.
게리 로우
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.