2012-12-19 117 views
8

我试图构建一个框架,允许人们通过实现一个接口来扩展我们的核心功能。下面是这个界面的一个简单例子。方法参数与参数对象

public interface MyInterface 
{ 
    IData GetData(string p1, char p2, double p3); 
} 

最近,我们已经决定修改这个接口(我知道我不应该打破相关的代码,但事实是我们没有任何第三方实现这个接口还,所以我们还有机会对于“重复”来正确实现这个接口)。

我们需要在此界面添加2个参数才能使我们的软件正常工作。有两种方法,我们正在考虑的只是将它们添加到签名是这样的:

public interface MyInterface 
{ 
    IData GetData(string p1, char p2, double p3, bool p4, DateTime p5); 
} 

,或者通过创建参数对象这样

public class MyParameters 
{ 
    public bool p4 { get; set; } 
    public DateTime p5 { get; set; } 
} 

并将它们添加到像这样的方法结束:

public interface MyInterface 
{ 
    IData GetData(string p1, char p2, double p3, MyParameters p4); 
} 

我正在寻找某种指导,以哪种方式进行“最正确”的方式。我可以看到两种类型的优点和缺点,但我不希望我的偏见导致我走错了路。

我的一些主要问题是:软件的

  • 可扩展性 - 我希望用户能够通过实现界面
  • 可维护性做的事情我还没有考虑过的 - 在理想情况下,我想从来没有触摸到了负责调用getData()再次
  • 清洁API代码 - 我不想我到达使溶液第三方开发者畏缩

我甚至不知道要问什么问题在线获取有关此问题的指导。我有一种感觉,答案是“它取决于”(关于p1-p5与GetData()函数的目的是如何相关的),但是有人能指出我应该请求帮助我评估的问题列表一种解决方案是否比另一种更好?

相关: Post 1 Post 2

回答

2

让我试图回答这个问题。让我们来评估你的选择:

1)如果下面的界面

public interface MyInterface 
{ 
    IData GetData(string p1, char p2, double p3); 
} 

被打破:

a)和不应该使用的话,那么你就应该强制执行者重写。所以改变方法定义。

public interface MyInterface 
{ 
    IData GetData(something else); 
} 

B),但你只需要鼓励用户使用新的定义,那么你可以创建一个新的重载告诉他们,第一个是过时的。

public interface MyInterface 
{ 
    //xml to tell them this is deprecated. 
    IData GetData(string p1, char p2, double p3); 
    IData GetData(string p1, char p2, double p3, and whatever); 
} 

关于你的新定义,有没有一站式的解决方案,任何人都可以在不知道有关模型给,但你会问自己,

I)“可以将参数本身代表着一个单一实体,如果合并?这是否意味着在现实世界中有一个单位的参数?“如果是这样,就这样做。如果没有,不要。当你处于这种困境时,我认为你应该依靠这种抽象层面的思维。我不确定俱乐部bool p4DateTime p5有什么意义。你应该club those那些在现实生活中代表着某些东西的参数。如果没有这些的组合是有道理的,那就把它留下。在这样的俱乐部中留下如此合乎逻辑的思维方式会让你获得更多的成功。请注意,您将自己的定义留给其他程序员,为了简化他们的工作,您的方法签名应该非常合乎逻辑。

II)这个班可以做更多的事情,而不仅仅是保存一组数据吗?类应该是这里的选项。

三)我是否需要只控制类的定义而不是执行它?在这种情况下,只需定义输入的公共接口,然后将实现留给客户。

四)未来我的界面的修改应该不会破坏现有的实现吗?重载是你要走的路。

假设您有两种选择,将签名平放,或留给俱乐部。

1)在不杵:

一个)更少的代码,减小另一层。

b)无需公开其他课程。

2)随着泡吧:

A)提供了一个更好的理解模型的进入功能 - 你的意图很明显。

b)如果您需要添加可选的细节来构建新形成的类,将来容易扩展。比方说你有一个类

class Input { 
    string p1; char p2; double p3; 

    public Input(string p1, char p2, double p3){ 
    } 
} 

和接口

public interface MyInterface 
{ 
    IData GetData(Input p1); 
} 

现在你可能要添加像一个布尔值和一个DateTime可选细节。既然它们是可选的,你不必在构造函数中强制它。您仍然可以拥有相同的构造函数,并为用户提供在构造函数外部进行修改的权限。

class Input { 
    string p1; char p2; double p3; bool p4; DateTime p5; 

    public Input(string p1, char p2, double p3){ 
    } 
} 

接口仍然可以是相同的。正如我所说的,推导这种类型的东西可悲地依赖于你的模型。简而言之,如果一个分组可能意味着什么,那么将它作为一个类或接口(取决于谁将控制逻辑)。

2

为什么不走一路:

public Interface IParameters 
{ 
    string p1 {get; set;} 
    char p2 {get; set;} 
    double p3 {get; set;} 
    bool p4 { get; set; } 
    DateTime p5 { get; set; } 
} 

public interface MyInterface 
{ 
    IData GetData(IParameters p); 
} 
+0

对于参数类型有一个接口是一个好主意,但考虑到接口不能被版本化,如果API会传播,那么没有人可以在不破坏存在的情况下向参数类型添加加号功能(比如再添加一个参数)码。 –