2014-04-14 1 views
1

인터페이스에 프로그래밍을하고 구체적인 클래스가 아니라고 생각했습니다.하지만 어떤 인터페이스 메소드가 구체적인 클래스에 대한 참조를 보유 할 수 있어야합니까?구체적인 클래스를 매개 변수로 참조하는 인터페이스 메소드가 결합을 유발합니까?

는 다음과 같은 시나리오를 가정 :

1)

public interface AbsType1 { 
    public boolean method1(int a); // it's ok, only primitive types here 
} 

2)

public interface AbsType2 { 
    public boolean method2(MyClass a); // I think I have some coupling here 
} 

나는 후자를 방지하기 위해 여기에 다른 디자인을 선택해야할까요? 예 : 나는 다른 사람이 그렇게보고 있지만

public interface MyInterface {} // yes, this is empty 

public classe MyClass implements MyInterface { 
    // basically identical to the previous "MyClass" 
} 


public interface AbsType2 { 
    public boolean method2(MyInterface a); // this is better (as long as the 
              // interface is really stable) 
} 

그러나 나를 설득하지 않는 무언가가 거기에 여전히 ... 나는 빈 인터페이스를 선언과 불편. 어쩌면 추상 클래스가 더 잘 작동할까요?

나는 조금 혼란 스럽다.

편집 :

좋아, 내가 예를함으로써 더 구체적으로하려고합니다. 이제 나는 ShopCart을 desining 그리고 난이 장바구니에 항목을 추가 할 물론 원하는 가정 해 봅시다 :

public interface ShopCart { 
    public void addArticle(Article a); 
} 

을 지금의 기사 구체적인 클래스 인 경우에, 어떤 구현 변경 시간이 지남 경우? 이것이 내가 인터페이스라고 생각할 수있는 이유이지만, 인터페이스가 동작을 지정해야하고 기사에 아무 것도 없다 (또는 거의 없다 ...) 나는 일종의 엔티티라고 생각하기 때문에 적어도 의미 론적 수준에서는 적합하지 않을 것이다. 수업).

아마도이 기사를 추상적 인 수업으로 만드는 것이 최선일 것이라는 결론을 내릴 수있을 것입니다. 어떻게 생각하십니까?

+1

나는 괜찮은 것을 볼 수 있습니다. –

+0

왜 인터페이스를 비어 있다고 선언합니까? 'AbsType'이 신경 써야 할'MyClass'에 관련된 public 메소드가 있습니까? - 없으면 클래스 유형에 제네릭을 사용하는 것이 좋습니다. – JimmyB

답변

1

내 생각에 Interfaces은 구현 유형이 다를 수있는 모든 유형에 적합합니다. 그러나 새 유형을 도입하는 module을 정의하는 경우 대체 구현을 의도하지 않으므로 처음에는 Interface으로 정의 할 필요가 없습니다. 종종 이것은 내 의견으로는 과도한 디자인 일 것입니다. 그것은 문제 영역과 종종 테스트 또는 AOP- 제직 지원 방법에 따라 다릅니다.

예를 들어 Location을 유형으로 모델링해야하는 2D 문제 도메인을 고려해보십시오. Location이 항상 xy 좌표로 표시되는 것이 분명하면 Class으로 제공 할 수 있습니다. 그러나 Location이 가질 수있는 속성 (GPS 데이터, x, y, z 좌표 등)을 알지 못하지만 distance()과 같은 일부 동작에 의존한다면 대신 인터페이스로 모델링해야합니다.

+0

이 답변을 주셔서 감사합니다, 그것은 매우 명확합니다 :) – tmh

2

컴포지션이 상속보다 훨씬 뛰어나므로 인터페이스를 사용합니다. "모든 인터페이스 메소드가 구체적인 클래스에 대한 참조를 보유 할 수 있어야합니까?", 왜 그렇게해서는 안됩니까? 패키지 내의 일부 클래스는 결합되어 있으며 사실이며 일반적인 사용 방법입니다. 인터페이스에이 릴레이션을 표시하면 어떤 클래스가 구현에 종속되는지 알 수 있습니다. 의존성 또는 구성 관계는 상속이 아니므로 추상 클래스를 피할 것입니다.

+0

예를 들어 ... 그 특정 경우에 추상 클래스도 피할 것이라고? 너는 무엇을 할 것이냐? – tmh

+0

우리는 유사하게, 나는 또한 기사 초록을 만들 것이라고 생각한다. 이것은 명확하게 상속 관계이지만, ShopCart는 엔터티 기사에서 작동하는 동작을 지정하므로 인터페이스 여야한다. –

1

AbsTypeMyClass에 액세스 할 공용 방법이없는 경우 빈 인터페이스는 아마도 좋은 방법이 아닙니다.

정적 메서드에 대한 인터페이스 선언 (계약)이 없습니다. 그렇지 않으면 여기에서 의미가 있습니다.

따라서 의 메소드를 MyClass/MyInterface에서 사용하지 않으면 기본적으로 다른 용도로만 클래스 객체를 저장한다고 가정합니다. 이 경우, <C extends Class<?>> 유형을 교환하여 필요한 경우 할 수 있도록 그런 다음 클래스의 유형을 제한 할 수 있습니다

public class AbsType3<C extends Class<?>> { 

    public boolean method3(T classType) {...} 

} 

처럼, 당신은 AbsType 클라이언트의 코드에 밀접하게 연결하지 않고 사용하는 방법을 명확하게하기 위해 제네릭 사용을 고려 매개 변수는 <C extends Class<Collection<?>>>과 같은 인터페이스가 될 수 있습니다.

빈 인터페이스는 클래스의 부울 플래그와 비슷합니다. 클래스가 인터페이스를 구현하는지 (true) 또는 구현하지 않는지 (false)를 결정합니다. 이 마커 인터페이스는 클래스 사용 방법 (또는 사용하지 않을 것임)에 대한 중요한 설명을 전달하는 데 사용해야합니다 (예 : Serializable 참조).

+0

예제를 제공했는데 ... 제네릭을 사용할 필요가 없다고 생각합니다. 어떻게 생각해? – tmh

+0

네 말이 맞아. 따라서 실제로 메서드에 전달 된 개체를 사용하려면 인터페이스, 추상 클래스 또는 구체적인 클래스에 대한 접근 방식을 취할 수 있습니다. 커플 링을 최소화하기 위해 실제로 인터페이스를 사용하는 것이 좋습니다. 물론 인터페이스가 구체적인 구현만큼 계약을 시행 할 수는 없지만 인터페이스가 신중하게 설계된 경우 반드시 문제가되는 것은 아닙니다. Otoh, (추상적 인) 기본 구현에서 'final'메소드를 사용하지 않는 한 계약을 시행 할 방법이 없습니다. 모든 메소드는 계약 위반 행위로 대체 될 수 있습니다. – JimmyB

+0

인터페이스로 이동하십시오. – JimmyB

관련 문제