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

Jon*_*ter 5 c# c#-4.0

我有一个我无法弄清楚的设计问题.这是我得到的:

一般来说,我有两种常见类型的对象Strikes和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;}
}
Run Code Online (Sandbox Code Playgroud)

现在,这一切都很好,但是让我说我​​已经有了以下方法来对IOption隐含卷执行一些"数学"

public double SquareImpliedVol(IOption opt)
{
   return Math.Pow(opt.ImpliedVol,2);
}
Run Code Online (Sandbox Code Playgroud)

同样,不是问题,但是当我为我的测试编写一些模拟对象时,我不清楚是否需要实现Bid和Ask.我没有,但我不知道除非我知道SquareImpliedVol里面的内容,这意味着我正在编写针对代码的测试,这很糟糕.

所以为了解决这个问题,我可以创建另一个只包含ImpliedVol属性的接口IOptionImpliedVol,然后让IOption继承自IOptionImpliedVol,就像这样

interface IOption : IOptionImpliedVol
{
   double Bid{get;set;}
   double Ask{get;set;}
}
Run Code Online (Sandbox Code Playgroud)

然后我们可以切换SquareImpliedVol

public double SquareImpliedVol(IOptionImpliedVol opt)
{
   return Math.Pow(opt.ImpliedVol,2);
}
Run Code Online (Sandbox Code Playgroud)

而且我们很棒.我可以写模拟对象,一切都很甜蜜.除了....我想编写一个将在List上运行的方法,但我需要的唯一属性是IStrike,它是Call.ImpliedVol和Put.ImpliedVol.我想创造类似的东西

interface IStrikeImpliedVol
{
   IOptionImpliedVol Call;
   IOptionImpliedVol Put;
}
Run Code Online (Sandbox Code Playgroud)

然后我也可以

interface IStrike : IStrikeImpliedVol
{
   IOption Call;
   IOption Put;
}
Run Code Online (Sandbox Code Playgroud)

除非这不合法.我觉得必须有某种设计模式,我可以解决这个问题,但我陷入了某种组合和继承的网络.

Sno*_*ear 5

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

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

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

  • +1表示初始设计是正确的.我很确定你没有*想要使用`IOptionImpliedVol`和`IStrikeImpliedVol`接口; 什么时候结束?you yoursef(Jonathan)已经给出了一个非常恰当的术语来描述这导致你失败​​的道路:一个混乱,复杂的*web*.听听Snowbear. (2认同)