2009-08-07 2 views
1

인터페이스 및 추상 기본 클래스가있는 객체 지향 디자인을 사용하는 현명한 사람들에게 몇 가지 질문이 있습니다. 다음 시나리오를 고려하십시오.개체 지향 -이 인터페이스 선언을 배치 할 위치

나는 추상적 인 저음 클래스 "DataObjectBase"와 파생 클래스 "UserDataObject"가 있습니다. 또한 "IDataObject"인터페이스가 있습니다. 물론 인터페이스는 내 데이터 객체가 공개해야하는 모든 공용 메소드 및 속성을 노출하므로 모든 데이터 객체에 공통된 메소드 및 속성을 추상 기본이 구현한다고 추측 할 수 있습니다.

내 기본 질문은 추상 저음 클래스 인 DataObjectBase가 인터페이스 IDataObject에 지정된 모든 것을 구현하는 경우 기본 클래스 또는 파생 클래스에서 인터페이스를 선언해야합니까?

기본 클래스에서 선언 된 C# 인터페이스에서는 파생 클래스에 implicity가 적용되지만 이는 최선의 방법입니까? 기본 클래스에 인터페이스를 구현하면 파생 클래스가 인터페이스를 구현한다는 것이 명확하지 않지만 각 파생 클래스에 대해 인터페이스가 다시 지정되어야합니다.

또한 기본 클래스가 추상 클래스가 아닌 경우 reccomendation이 변경됩니까?

두 번째 하위 질문 : 기본 클래스가 IDataObject 인터페이스의 모든 메서드/속성을 구현하는 경우에도 인터페이스가 필요합니까? 기본 클래스 typename은 인터페이스 이름 대신 다음과 같이 간단하게 사용할 수 있습니다.

private DataObjectBase _dataObject;
private IDataObject _dataObject;

위 예제 (여기서베이스는 인터페이스에 의해 노출 된 모든 것을 구현 함)에서 두 파생 클래스 모두 동일한 파생 유형을 할당 할 수 있습니다. 개인적으로 나는 항상 이러한 상황에서 인터페이스를 사용하지만, 사람들의 생각을 듣고 나는 intrested입니다.

미리 감사드립니다.

답변

1

이러한 문제에 대한 내 사고 방식은 코드를 읽는 다른 사람들, 당신이 원한다면 "역할"을 고려하는 것입니다. 또한 시스템의 전반적인 유지 보수 가능성을 고려하십시오.

처음에는 인터페이스를 사용할 것으로 예상되는 코드가 있습니다. 이것은 인터페이스 측면에서 작성된 것으로 작성자는 구현에 관심이 없어야합니다. 그래서 우리는 Interface 클래스를 제공합니다. 이러한 관점에서 추상 기본 클래스는 가능한 많은 구현 계층 중 하나 일뿐입니다. 구현 세부 사항에 대해이 역할을 말하지 마십시오. 인터페이스 유지.

그러면 구현을 설계하는 역할을 담당하게됩니다. 그들은 하나의 가능한 접근법을 제시하고 약간의 변형을 발견하므로 공통 코드를 모으고 자합니다.추상 기본 클래스 - 여기에 공통적 인 내용을 채우십시오. 자세한 구현자가 틈을 채우십시오. "귀하의 코드는 여기에 있습니다"라는 추상적 인 방법을 제공하여 그들을 도와주십시오. 이 메소드는 인터페이스의 메소드 일 필요는 없습니다. 또한이 추상 기본 클래스는 하나 이상의 인터페이스를 구현할 수도 있습니다. (예 : CleverThingWorker이지만 IntermediateWorkPersister입니다.)

그러면 우리는 실제로 세부적인 구현을 담당합니다. 여기 간격을 채우십시오. 이해하기 쉬운 데드. 이 경우 인터페이스를 고려하지 않아도됩니다. 당신의 임무는 그 추상 클래스를 구체적으로 만드는 것입니다.

결론 ... 인터페이스와 기본 클래스를 모두 사용합니다. 인터페이스를 기본 클래스에 놓습니다. 구현 클래스에 값을 추가하여 값을 추가하지 않습니다.

1

사용자 클래스가 인 경우 항상이 하나의 기본 클래스에서 상속 될 경우 인터페이스가 필요하지 않습니다. 인터페이스와 일치하지만 기본 클래스에서 파생되지 않은 클래스가있을 가능성이있는 경우 인터페이스를 사용하십시오.

인터페이스가 기본 클래스에서 숨겨져 있고 사용자 클래스에서 즉시 볼 수없는 인터페이스는 정상이며 컴파일러에서 처리 할 수 ​​있습니다. 이것은 좋은 명명 규칙이 나오는 곳이기도합니다. UserDataObject는 DataObjectBase와 마찬가지로 IDataObject와 일치하는 이름을가집니다. 클래스 파일에 IDataObject에서 상속 받았다고하는 주석을 추가 할 수 있지만 IDataObject에서 상속받은 DataObjectBase에서 상속받은 것으로 볼 수 있습니다.

0

언급해야 할 또 다른 사항은 인터페이스를 사용하면 자동화 된 테스트를보다 쉽게 ​​구현할 수 있다는 것입니다.

예를 들어, 인터페이스의 메소드 중 하나가 예외 (예 : 'DatabaseConnectionLostException')를 발생시키고 클라이언트 코드를 테스트하여 이러한 상황에서 올바르게 작동하는지 확인한다고 가정 해보십시오.

테스트를 작성할 수 있도록 예외를 throw하는 인터페이스 구현을 제공하는 것은 간단합니다.

인터페이스 대신 추상 기본 클래스를 사용한 경우이 작업은 다소 까다로울 수 있습니다. (확인해보십시오. 모의 (Mock)을 사용할 수 있지만 인터페이스 솔루션은 훨씬 깨끗합니다.)

관련 문제