인터페이스를 거의 사용하지 않고 다른 코드에서 공통적으로 사용됩니다.
또한 내 코드에서 드물게 하위 클래스와 슈퍼 클래스를 만듭니다 (내 클래스를 만드는 동안).
- 나쁜 일입니까?
- 이 스타일을 바꾸시겠습니까?
- 이 스타일에 부작용이 있습니까?
- 큰 프로젝트를 수행하지 않았기 때문입니까?
인터페이스를 거의 사용하지 않고 다른 코드에서 공통적으로 사용됩니다.
또한 내 코드에서 드물게 하위 클래스와 슈퍼 클래스를 만듭니다 (내 클래스를 만드는 동안).
답변:
인터페이스를 사용하려는 몇 가지 이유가 있습니다.
http://msdn.microsoft.com/en-us/library/3b5b8ezk(v=vs.80).aspx
인터페이스는 프로그래밍에서 다른 것과 같습니다. 필요하지 않으면 사용하지 마십시오. 나는 그것들이 스타일의 문제로 광범위하게 사용되는 것을 보았지만, 인터페이스가 제공하는 특별한 속성과 기능이 필요하지 않다면, "그 이유 때문에"그것들을 사용하는 것의 이점을 보지 못한다.
클래스 상속과 인터페이스는 모두 그 자리를 차지합니다. 상속은 "는"을 의미하고 인터페이스는 "동작"을 정의하는 계약을 제공합니다.
인터페이스를 더 자주 사용하는 것은 나쁜 습관이 아닙니다. 현재 Bill Wagner의 "효과적인 C #-C # 개선을위한 50 가지 구체적인 방법"을 읽고 있습니다. 항목 번호 22는 "인터페이스에 인터페이스를 정의하고 구현하는 것이 좋습니다"라고 인용합니다.
일반적으로 개념적으로 관련된 유형 간의 공통 동작의 특정 구현을 정의해야 할 때 기본 클래스를 사용합니다. 더 자주 인터페이스를 사용합니다. 사실, 나는 일반적으로 클래스를 만들 때 클래스에 대한 인터페이스를 정의하여 시작합니다 ... 결국 인터페이스를 컴파일하지 않더라도 공용 API를 정의하여 시작하는 것이 도움이된다는 것을 알았습니다. 시작부터 수업. 인터페이스를 구현하는 여러 클래스가 있고 구현 논리가 동일하다는 것을 알게되면 유형 간 공통 기본 클래스를 구현하는 것이 합리적인지 여부를 스스로에게 묻습니다.
Bill Wagners의 인용문은 다음과 같습니다.
모든 파생 클래스는 즉시 해당 동작을 통합합니다. 인터페이스에 멤버를 추가하면 해당 인터페이스를 구현하는 모든 클래스가 중단됩니다. 새로운 메소드를 포함하지 않으며 더 이상 컴파일되지 않습니다. 각 구현자는 새 멤버를 포함하도록 해당 유형을 업데이트해야합니다. 추상 기본 클래스와 인터페이스 중에서 선택하는 것은 시간이 지남에 따라 추상화를 가장 잘 지원하는 방법에 대한 문제입니다. 인터페이스 수정 : 모든 유형이 구현할 수있는 일련의 기능에 대한 계약으로 인터페이스를 릴리스합니다. 기본 수업은 시간이 지남에 따라 확장 될 수 있습니다. 이러한 확장은 모든 파생 클래스의 일부가됩니다. 두 개의 모델을 혼합하여 여러 인터페이스를 지원하면서 구현 코드를 재사용 할 수 있습니다. " 새로운 메소드를 포함하지 않으며 더 이상 컴파일되지 않습니다. 각 구현자는 새 멤버를 포함하도록 해당 유형을 업데이트해야합니다. 추상 기본 클래스와 인터페이스 중에서 선택하는 것은 시간이 지남에 따라 추상화를 가장 잘 지원하는 방법에 대한 문제입니다. 인터페이스 수정 : 모든 유형이 구현할 수있는 일련의 기능에 대한 계약으로 인터페이스를 릴리스합니다. 기본 수업은 시간이 지남에 따라 확장 될 수 있습니다. 이러한 확장은 모든 파생 클래스의 일부가됩니다. 두 개의 모델을 혼합하여 여러 인터페이스를 지원하면서 구현 코드를 재사용 할 수 있습니다. " 새로운 메소드를 포함하지 않으며 더 이상 컴파일되지 않습니다. 각 구현자는 새 멤버를 포함하도록 해당 유형을 업데이트해야합니다. 추상 기본 클래스와 인터페이스 중에서 선택하는 것은 시간이 지남에 따라 추상화를 가장 잘 지원하는 방법에 대한 문제입니다. 인터페이스 수정 : 모든 유형이 구현할 수있는 일련의 기능에 대한 계약으로 인터페이스를 릴리스합니다. 기본 수업은 시간이 지남에 따라 확장 될 수 있습니다. 이러한 확장은 모든 파생 클래스의 일부가됩니다. 두 개의 모델을 혼합하여 여러 인터페이스를 지원하면서 구현 코드를 재사용 할 수 있습니다. " 모든 유형이 구현할 수있는 일련의 기능에 대한 계약으로 인터페이스를 릴리스합니다. 기본 수업은 시간이 지남에 따라 확장 될 수 있습니다. 이러한 확장은 모든 파생 클래스의 일부가됩니다. 두 개의 모델을 혼합하여 여러 인터페이스를 지원하면서 구현 코드를 재사용 할 수 있습니다. " 모든 유형이 구현할 수있는 일련의 기능에 대한 계약으로 인터페이스를 릴리스합니다. 기본 수업은 시간이 지남에 따라 확장 될 수 있습니다. 이러한 확장은 모든 파생 클래스의 일부가됩니다. 두 개의 모델을 혼합하여 여러 인터페이스를 지원하면서 구현 코드를 재사용 할 수 있습니다. "
"코딩 인터페이스는 기본 클래스 유형으로 코딩하는 것보다 다른 개발자에게 더 큰 유연성을 제공합니다."
"인터페이스를 사용하여 클래스의 API를 정의하면 유연성이 향상됩니다."
"유형이 속성을 클래스 유형으로 노출하면 전체 인터페이스가 해당 클래스에 노출됩니다. 인터페이스를 사용하면 클라이언트가 사용할 메소드 및 속성 만 노출하도록 선택할 수 있습니다."
"기본 클래스는 관련 콘크리트 유형에서 공통적 인 동작을 설명하고 구현합니다. 인터페이스는 관련이없는 콘크리트 유형이 구현할 수있는 원자 적 기능을 설명합니다. 둘 다 그 위치를가집니다. 클래스는 생성 한 유형을 정의합니다. 인터페이스는 이러한 유형의 동작을 기능으로 설명합니다. 차이점을 이해하면 변화에보다 탄력적 인 표현 디자인을 더 많이 만들 수 있습니다. 클래스 계층 구조를 사용하여 관련 유형을 정의하십시오. 이러한 유형에 걸쳐 구현 된 인터페이스를 사용하여 기능을 노출하십시오. "
언급되지 않은 한 가지 테스트는 테스트입니다. 모든 C # mocking-library 및 Java에 대한 일부 클래스 는 인터페이스를 구현하지 않으면 클래스 를 조롱 할 수 없습니다 . 이는 애자일 / TDD 관행에 따라 모든 클래스에 고유 한 인터페이스 를 제공하는 많은 프로젝트를 이끌고 있습니다.
어떤 사람들은 이것이 "커플 링을 줄이므로"이 모범 사례를 고려하지만 동의하지 않습니다. 언어의 부족에 대한 해결책 일 뿐이라고 생각합니다.
인터페이스는 "동일한"것을 수행하지만 다른 방식으로 수행하는 두 개 이상의 클래스가있을 때 가장 잘 사용된다고 생각합니다.
예를 들어, 닷넷 프레임 워크의 가게에 나와있는 여러 클래스가 물건을 ,하지만 그들은 모두 저장하는 것이 다른 방식으로 물건. 따라서 추상 IList<T>
인터페이스 를 갖는 것이 합리적 이며 다른 인터페이스를 사용하여 구현할 수 있습니다.
또한 2+ 클래스를 상호 교환하거나 나중에 교체 할 수 있도록하려는 경우에도 사용해야합니다. 앞으로 목록을 저장하는 새로운 방법이 나오면 코드 전체에서 AwesomeList<T>
사용한다고 가정하면 사용 IList<T>
하도록 AwesomeList<T>
변경하면 수백 / 수천이 아닌 수십 줄만 변경하는 것을 의미합니다.
아니, 전혀 나쁘지 않다. 공통 인터페이스가있는 두 클래스를 런타임시 서로 바꿔야하는 경우에만 명시 적 인터페이스를 사용해야합니다. 상호 교환이 필요하지 않으면 상속받지 않아도됩니다. 그렇게 간단합니다. 상속은 깨지기 쉬우므로 가능하면 피해야합니다. 피하거나 제네릭을 대신 사용할 수 있다면 그렇게하십시오.
문제는 컴파일 타임 제네릭이 약한 C # 및 Java와 같은 언어에서 모든 클래스가 동일한 기반에서 상속되지 않으면 둘 이상의 클래스를 처리 할 수있는 하나의 메서드를 작성할 수 없기 때문에 DRY를 위반할 수 있다는 것입니다. C # 4 는 이것을 처리 dynamic
할 수 있습니다 .
문제는 상속은 전역 변수와 같습니다. 일단 변수를 추가하고 코드에 의존하면 하나님은 그것을 제거하도록 도와줍니다. 그러나 언제든지 추가 할 수 있으며 정렬 래퍼를 사용하여 기본 클래스를 변경하지 않고 추가 할 수도 있습니다.
몇 년 동안 인터페이스를 사용하지 않았습니다. 물론 이것은 몇 년 동안 Erlang에서 거의 독점적으로 프로그래밍 해 왔으며 인터페이스의 전체 개념이 존재하지 않기 때문입니다. (당신이 얻을 가장 가까운는 "행동"이며 정말 열심히 곁눈질하지 않는 한 그건 정말 같은 일이 아니에요 그리고 밖으로 눈의 구석의 그 봐.)
따라서 실제로 귀하의 질문은 패러다임에 의존하고 (이 경우 OOP) 또한 언어에 따라 다릅니다 (인터페이스가없는 OOP 언어가 있습니다).
상황이 바뀌고 있지만 ( MS Moles ) 인터페이스에 거의 독점적으로 코딩하는 것이 좋을 것이라고 생각하는 주된 이유는 인터페이스를 모의하고 자연스럽게 IoC 아키텍처에 적합시키기 때문입니다.
IMO 인터페이스 만 사용하거나 가능하면 완전히 바보 같은 DAO 만 사용해야합니다. 일단이 사고 방식에 들어 서면 인터페이스를 통해 자신을 노출시키지 않고 내가 정직해야 할 구체적인 객체를 통해 모든 것을 수행하는 라이브러리를 사용하기 시작하면 모든 것이 약간 어색해집니다.
구식 프로젝트의 경우 순환 참조는 장기적으로 큰 유지 관리 문제가 될 수 있으므로 순환 참조를 피하기 위해 인터페이스를 사용합니다.
나쁜:
class B; // forward declaration
class A
{
B* b;
};
class B
{
A* a;
}
나쁘지 않다:
class PartOfClassB_AccessedByA
{
};
class A
{
PartOfClassB_AccessedByA* b;
};
class B : public PartOfClassB_AccessedByA
{
A* a;
}
일반적으로 A, B, PartOfClassB_AccessedByA는 별도의 파일로 구현됩니다.