2011-03-18 3 views
5

알아낼 수없는 디자인 문제가 있습니다. 다음은 내가 가지고있는 것입니다 :C#에서 인터페이스와 합성 및 상속을 결합 할 수 있습니까?

일반적으로 두 가지 일반적인 유형의 오브젝트 인 Strikes and Options가 있습니다. 이들은 두 개의 인터페이스 IStrike와 IOption으로 추상화되어있다.

IOption에 다음과 같은 필드가 있다고 가정 해 봅시다. 실제로는 약 10 배의 크기가 있지만, 문제를 설명하기 위해 다음 세 가지를 사용할 수 있습니다.

interface IOption 
{ 
    double Bid{get;set;} 
    double Ask{get;set;} 
    double ImpliedVol{get;set;} 
} 


interface IStrike 
{ 
    IOption Call{get;set;} 
    IOption Put{get;set;} 
} 

자, 즉, 잘 좋은,하지만의 내가 아닌 문제가 다시 르십시오 암시 권

public double SquareImpliedVol(IOption opt) 
{ 
    return Math.Pow(opt.ImpliedVol,2); 
} 

일부 "수학"을 수행하기위한 다음과 같은 방법을 가지고 말을 할 수 있지만, 테스트를 위해 모의 객체를 작성할 때 Bid 및 Ask을 구현해야하는지 명확하지 않습니다. 나는 모르지만, SquareImpliedVol 내부에 배짱이 있다는 것을 알지 못한다면, 나는 그것을 알지 못한다. 이는 코드에 대한 테스트를 작성하고 있다는 것을 의미한다.

그래서이 문제를 해결하려면, 난 그냥 ImpliedVol 속성을 포함하는 다른 인터페이스 IOptionImpliedVol를 만들 수 있습니다, 다음 르십시오 그렇게

interface IOption : IOptionImpliedVol 
{ 
    double Bid{get;set;} 
    double Ask{get;set;} 
} 

처럼 IOptionImpliedVol에서 상속이 그리고 우리는

public double SquareImpliedVol(IOptionImpliedVol opt) 
{ 
    return Math.Pow(opt.ImpliedVol,2); 
} 
SquareImpliedVol을 전환 할 수 있습니다

그리고 우리는 훌륭합니다. 나는 모의 물건을 쓸 수 있으며 모든 것이 멋지다. 예외 ... 목록에서 작동 할 메서드를 작성하려고하지만 IStrike에서 필요한 유일한 속성은 Call.ImpliedVol 및 Put.ImpliedVol입니다. 나는

interface IStrikeImpliedVol 
{ 
    IOptionImpliedVol Call; 
    IOptionImpliedVol Put; 
} 

같은 것을 만들려하고이 정당하지 않은 경우를 제외하고 다음 나는 또한

interface IStrike : IStrikeImpliedVol 
{ 
    IOption Call; 
    IOption Put; 
} 

있을 수 있습니다. 나는 이것을 해결할 수있는 일종의 디자인 패턴이 있어야만하는 것처럼 느껴지지만, 나는 일종의 구성과 상속의 웹에 갇혀있다.

답변

5

2 개의 인터페이스가있는 초기 디자인이라고 생각합니다. Bid/Ask을 설정할시기와 테스트에서 설정하지 않을 때를 알아야하고, 귀찮게한다는 것을 말해야합니다.

다른 지점에서 보도록하겠습니다. 일부 기능에 대한 테스트를 작성하고 있습니다 (다시 SquareImpliedVol라고 가정 해 봅시다). 이 함수를 올바르게 구현하면 ImpliedVol 속성 만 신경 써야하지만 Bid/Ask 함수는 예외이므로 공백으로 둘 수 있습니다. Bid/Ask이 설정되지 않은 상태에서 기능이 실패하면 유닛 테스트에서 문제가 발생했습니다. 물론 비어있는 경우 Bid/AskOption 객체의 상태가 잘못되었지만 문제가되지는 않습니다.

다른 말로하면 특정 방법이 작동하는 방법에 대한 지식에 대한 테스트를 작성하고 있으며이 지식이 해당 기능에 이미 기록 된 코드와 상호 연관된다는 사실에 아무런 문제가 없음을 말씀드립니다.

+2

처음 디자인이 올바른 아이디어. IOptionImpliedVol과 IStrikeImpliedVol 인터페이스를 사용하기를 원하지는 않습니다. 언제 끝날까요? 당신의 조셉 (Jonathan)은 이미 당신을 이끌어가는 경로를 설명하기 위해 매우 어리숙하고 복잡한 * 웹 *이라는 용어를 사용했습니다. 스노우 베어를 들어보세요. –

+0

감사합니다. 때로는 디자인으로 약간의 재미를 느낄 수 있으며, StackOverflow와 같은 커뮤니티를 통해 내가 생각할 때 이야기 할 수 있다는 점이 좋습니다. –

0

이 문제를 처리 할 수있는 방법은 여러 가지가 있지만 해결해야 할 문제는 해결책이 아니라 다른 사람이 처리하는 방법입니다.

예를 들어, 많은 사람들이 조롱하는 객체로 "IOption 객체를 사용하는 테스트"를 해결할 것이지만 실제로 IOption의 어느 부분이 실제로 사용되는지 신경 쓰지 않을 것입니다. 즉, 약간 잘못되었습니다. mocking 객체를 생성하기 위해 조롱 라이브러리를 사용하는 코드를 살펴보면 다음과 같은 코드를 작성하기 때문에 인터페이스의 어느 부분이 사용되는지 명확히 알 수 있습니다.

var mock = CREATE MOCK OF TYPE IOption 
ON MOCK mock, EXPECT CALL TO ImpliedVol 
    FOR THAT CALL, RETURN 15 

test code 

VERIFY THAT CALLS WERE MADE AS EXPECTED 

만족 스럽다면 NMock 또는 이와 유사한 일반 조롱 라이브러리를 사용하여 인터페이스 용 조롱 개체를 만들 수 있습니다. 도서관에서 "나는이 코드 도중 이 아니고가 입찰을 요청합니다."라고 말할 수 있습니다. 따라서이 코드가 도움이 될 것입니다.

그러나 테스트하고 계량하기가 어려운 것에 대비하고 있습니다. 예, 예상되는 부작용이 실제로 발생했는지 확인할 수 있습니다. 다른 부작용이 발생하지 않았다는 것을 어떻게 확인합니까? 예를 들어, 미래에 누군가가 인터페이스에 새로운 메소드를 추가하면 어떻게 될까? 모든 단위 테스트 또는 그 중 하나 또는 모두가 해당 추가 메소드에 대한 호출이 기존 테스트에 대해 호출되지 않았는지 확인하는 방법은 무엇입니까?

중요합니까?

관련 문제