인터페이스가 다른 인터페이스를 확장하고 메소드를 상속해야 함


13

이것은 일반적인 질문이지만 현재 겪고있는 문제와 관련이 있습니다. 현재 솔루션에 지정된 인터페이스가 있습니다.

public interface IContextProvider
{
   IDataContext { get; set; }
   IAreaContext { get; set; }
}

이 인터페이스는 프로그램 전체에서 자주 사용되므로 필요한 개체에 쉽게 액세스 할 수 있습니다. 그러나 프로그램의 상당히 낮은 수준에서 IAreaContext 를 사용 하고 일부 작업을 수행 하는 다른 클래스에 액세스해야 합니다. 그래서이 창조를 위해 또 다른 팩토리 인터페이스를 만들었습니다.

public interface IEventContextFactory 
{
   IEventContext CreateEventContext(int eventId);
}

IContextProvider 를 구현하고 NinJect를 사용하여 주입 되는 클래스가 있습니다. 내가 가진 문제는이 IEventContextFactory 를 사용해야하는 영역 은 IContextProvider 에만 액세스 할 수 있으며 자체적 으로이 새로운 인터페이스가 필요한 다른 클래스를 사용한다는 것입니다. 이 IEventContextFactory 구현을 낮은 수준 으로 인스턴스화 하고 싶지 않고 전체적으로 IEventContextFactory 인터페이스 와 함께 작동 합니다. 그러나 나는 또한 그것을 필요로하는 클래스에 전달하기 위해 생성자를 통해 다른 매개 변수를 주입하고 싶지 않습니다.

// example of problem
public class MyClass
{
    public MyClass(IContextProvider context, IEventContextFactory event)
    {
       _context = context;
       _event = event;
    }

    public void DoSomething() 
    {
       // the only place _event is used in the class is to pass it through
       var myClass = new MyChildClass(_event);
       myClass.PerformCalculation();      
    }
}

그래서 내 주요 질문은 이것이 수용 가능 할까, 아니면 이와 같은 것을하는 것이 일반적이거나 좋은 습관인지입니다 (인터페이스는 다른 인터페이스를 확장합니다).

public interface IContextProvider : IEventContextFactory

또는 내가 원하는 것을 달성하기위한 더 나은 대안을 고려해야 하는가? 제안을 제공하기에 충분한 정보를 제공하지 않은 경우 알려 주시면 더 많은 정보를 제공 할 수 있습니다.


2
인터페이스가 실제로 아무것도 구현하지 않기 때문에 질문 제목을 "인터페이스가 인터페이스를 상속해야합니까?"로 바꾸겠습니다.
Jesse C. Slicer

2
일반적인 언어는 인터페이스가 부모 인터페이스를 "확장"하고 (그러므로) 부모 인터페이스의 메소드를 "상속"한다는 것이므로 여기서 "extend"를 사용하는 것이 좋습니다.
Theodore Murdock

인터페이스는 부모를 확장시킬 수 있는데 왜 나쁜 습관이 될까요? 하나의 인터페이스가 합법적으로 다른 인터페이스의 수퍼 세트라면 당연히 확장해야합니다.
Robin Winslow

답변:


10

인터페이스는 구현없이 동작 만 설명하지만 상속 계층에 계속 참여할 수 있습니다. 예를 들어,의 일반적인 아이디어가 있다고 가정 Collection합니다. 이 인터페이스는 멤버를 반복하는 방법과 같이 모든 컬렉션에 공통적 인 몇 가지 사항을 제공합니다. 그런 다음 a List또는 a 와 같은보다 구체적인 개체 컬렉션에 대해 생각할 수 있습니다 Set. 이들 각각은의 모든 동작 요구 사항을 상속 Collection하지만 특정 유형의 콜렉션에 특정한 추가 요구 사항을 추가합니다.

인터페이스에 대한 상속 계층 구조를 만드는 것이 합리적이라면 언제든지해야합니다. 두 개의 인터페이스가 항상 함께 발견되면 아마도 병합되어야합니다.


6

그렇습니다. 다음과 같은 질문을하고 하나 이상이 적용되는 경우 다른 인터페이스를 상속해도됩니다.

  1. 인터페이스 A가 인터페이스 B를 논리적으로 확장합니다 (예 : ICollection에 기능을 추가하는 IList).
  2. 인터페이스 A는 다른 인터페이스에 의해 이미 지정된 동작을 정의해야합니다 (예 : 정리할 자원이있는 경우 IDisposable 구현 또는 반복 될 수있는 경우 IEnumerable 가능).
  3. 인터페이스 A의 모든 구현에는 인터페이스 B에 지정된 동작이 필요합니까?

귀하의 예에서, 나는 그것이 그렇다고 대답한다고 생각하지 않습니다. 다른 속성으로 추가하는 것이 좋습니다.

public interface IContextProvider
{
   IDataContext DataContext { get; set; }
   IAreaContext AreaContext { get; set; }
   IEventContextFactory EventContextFactory { get; set; }
}

인터페이스를 확장하는 것보다 속성을 더 좋게 만드는 방법은 무엇입니까? 아니면 고양이가 말하도록 피부를 바르는 또 다른 방법입니까?
dreza

1
차이점은 당신이 만드는 경우이다 IContextProvider확장 IEventContextFactory, 다음 ContextProvider구현이 너무 메소드를 구현해야합니다. 당신은 속성으로 추가하는 경우, 당신은 그 말 ContextProvider을 가지고 IEventContextFactory있지만 실제로 구현 세부 사항을 알고하지 않습니다.
Trevor Pilley

4

예, 한 인터페이스를 다른 인터페이스로 확장해도됩니다.

특정 경우에 옳은 일인지에 대한 질문은 둘 사이에 "is-a"관계가 있는지에 달려 있습니다.

유효한 "is-a"관계에 필요한 것은 무엇입니까?

먼저, 두 인터페이스 간에는 실질적인 차이가 있어야합니다. 즉, 하위 인터페이스가 아닌 상위 인터페이스를 구현하는 인스턴스가 있어야합니다. 두 인터페이스를 모두 구현하지 않는 인스턴스가 없거나 존재하지 않을 경우 대신 두 인터페이스를 병합해야합니다.

둘째로, 자식 인터페이스의 모든 인스턴스가 반드시 부모의 인스턴스 여야하는 경우가되어야합니다. 부모 인터페이스

둘 다 참이면 상속은 두 인터페이스에 대한 올바른 관계입니다.


기본 인터페이스 만 사용하고 파생 된 인터페이스는 사용하지 않는 클래스는 필요하지 않습니다. 예를 들어 IReadOnlyList모든 목록 클래스 IList가 (에서 파생 된 IReadOnlyList) 구현하더라도 인터페이스 가 유용 할 수 있습니다 .
svick

1

한 인터페이스가 항상 다른 인터페이스 를 요구 / 제공하려는 경우 계속 진행하십시오. 나는 이것이 의미가있는 몇 가지 경우에서 이것을 보았습니다 IDisposible. 그러나 일반적으로 인터페이스 중 하나 이상이 책임보다 특성과 유사하게 작동하는지 확인해야합니다.

귀하의 예를 들어, 명확하지 않습니다. 둘 다 항상 함께 있으면 하나의 인터페이스 만 만드십시오. 하나가 항상 다른 하나를 필요로한다면, 나는 종종 여러 책임 및 / 또는 다른 유출 추상 문제로 이어지는 "X 및 1"종류의 상속에 대해 걱정할 것입니다.


고마워 책임보다 특성처럼 행동한다는 것은 무엇을 의미합니까?
dreza

@dreza 저는 SOLID의 SRP에서와 같이 책임을, 스칼라 특성과 같은 특성을 나타냅니다. 대부분 인터페이스가 문제를 모델링하는 방법 의 개념 . 문제의 주요 부분 또는 다른 유형의 다른 유형에 대한 관점을 나타 냅니까?
Telastyn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.