我可以将组合和继承与C#中的接口结合起来吗?

问题描述:

我有一个设计问题,我找不出来。这里是我得到的:我可以将组合和继承与C#中的接口结合起来吗?

一般来说,我有两个一般类型的对象罢工和选项。这些已被抽象为两个接口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;} 
} 

现在,这一切都很好,但让我们说,我已经得到了对-i选项隐含卷

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

执行一些“数学”再一次,不是一个问题下面的方法,但当我为测试编写一些模拟对象时,我不清楚是否需要实施出价和询问。我不知道,但我不知道,除非我知道SquareImpliedVol内部的胆量,这意味着我正在写代码测试,这是不好的。

因此,要解决这个问题,我可以创建只包含ImpliedVol财产另一个接口IOptionImpliedVol,然后有-i选项从IOptionImpliedVol继承像这样

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

然后我们可以切换多达SquareImpliedVol

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

我们很棒。我可以写模拟对象,一切都很美好。除了....我想写一个将在列表上运行的方法,但我需要从IStrike获得的唯一属性是Call.ImpliedVol和Put.ImpliedVol。我想创造这样

interface IStrikeImpliedVol 
{ 
    IOptionImpliedVol Call; 
    IOptionImpliedVol Put; 
} 

,然后我也可以有

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

除了不合法的。我觉得必须有某种设计模式才能解决这个问题,但是我陷入了某种构图和继承的网络中。

我认为你是两个接口的初始设计是正确的。你说你必须知道什么时候设置Bid/Ask以及什么时候不在你的测试中设置它并且困扰你。

让我们试着从其他角度来看待它。你正在编写一个函数的测试(假设它是你的SquareImpliedVol)。你知道,正确实施这个功能应该只关心ImpliedVol属性,而不是关于Bid/Ask,所以你可以留下这些空白。如果函数失败并且未设置Bid/Ask那么你的单元测试发现了一个问题 - 很高兴。当然,如果空的Bid/AskOption对象的不正确状态,但这在您的情况下似乎不是问题。

换句话说,我会说你在应该如何具体的工作方法写一个测试对你知识并没有什么错在这方面的知识和已经写入功能码相关的事实。

+2

+1表示初始设计是正确的。我非常确定你*不*想使用'IOptionImpliedVol'和'IStrikeImpliedVol'接口;什么时候结束? Yoursef(乔纳森)已经给出了一个非常恰当的术语来描述这导致你失败​​的路径:一个混乱,复杂的*网站*。听Snowbear。 – 2011-03-18 20:39:40

+0

谢谢。有时候我会对设计有点迂腐,当我认为可能会发生时,有一个像*这样的社区可以与之交谈真是太棒了。 – 2011-03-21 12:08:53

有很多方法可以解决这个问题,但主要问题是您期望解决方案是什么,而不是其他人如何处理它。

例如,很多人会解决“测试的东西,需要一个-i选项对象”用嘲讽的对象,但他们当然不会是任何接近关怀实际上是用什么-i选项的一部分。也就是说,这是有点不对的,因为如果你开始看看使用模拟库生成嘲讽对象的代码,他们清楚地知道接口的哪个部分被使用,因为它们会编写看起来像这样的代码:

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或类似,以生产嘲讽的对象为你的接口。你可以和那些图书馆一起说,“我的不是期望在此代码期间致电投标”,所以它应该适合你。

但是,你对撞的东西是非常难以检测和量化。是的,您可以验证预期的副作用是否确实发生。除非你知道所有的副作用,否则你如何确认没有发生其他副作用?例如,如果将来某人在接口中添加了一种新的方法。你如何确保所有的单元测试或其中的任何单元测试或者任何单元测试都没有,从而验证对这个额外方法的调用从未被调用过现有的测试。

重要吗?