C# 方法参数与参数对象
我试图构建一个框架,允许人们通过实现一个接口来扩展我们的核心功能。下面是这个界面的一个简化示例C# 方法参数与参数对象,c#,parameter-object,C#,Parameter Object,我试图构建一个框架,允许人们通过实现一个接口来扩展我们的核心功能。下面是这个界面的一个简化示例 public interface MyInterface { IData GetData(string p1, char p2, double p3); } 最近,我们决定修改这个接口(我知道我不应该破坏依赖代码,但事实是我们还没有任何第三方实现这个接口,所以我们有机会“重做”来正确实现这个接口) 我们需要在这个界面上再添加2个参数,这样我们的软件才能正常工作。我们考虑的两种方法是将它们添加
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-我不希望我达成的解决方案让第三方开发人员畏缩
为什么不一直走下去:
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);
}
让我试着回答这个问题。让我们评估一下您的选择: 1) 如果出现以下界面
public interface MyInterface
{
IData GetData(string p1, char p2, double p3);
}
public interface MyInterface
{
IData GetData(Input p1);
}
已损坏:
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);
}
关于你的新定义,没有任何人可以在不了解模型的情况下给出一站式解决方案,但是你问自己
一) “如果组合起来,参数本身是否可以表示单个实体?在现实世界中,有一个单位的参数是否意味着什么?”如果是,请这样说。如果没有,请不要。我认为当你处于这种两难境地时,你应该依靠这种抽象层次的思考。我不确定在夜总会玩boolp4
和DateTime p5
有什么意义。你应该使用那些在现实生活中代表某些东西的参数。如果这些组合都没有意义,那么就让它保持原样。你将有更多的成功离开这样的俱乐部,以这样的逻辑思维方式。请注意,您将您的定义留给其他程序员,为了简化他们的工作,您的方法签名应该非常符合逻辑
二) 相对于仅仅保存一组数据,类可以做更多的事情吗?类应该是这里的选项
三) 我是否只需要控制类定义而不需要控制它的实现?在这种情况下,只需定义输入的公共接口,并将实现留给客户
四) 将来对接口的修改是否应该不会破坏现有的实现?超载是你的出路
假设你有两个选择,留下签名,或者加入俱乐部
1) 不使用棍棒:
a) 减少代码,减少另一层
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(string p1, char p2, double p3);
}
public interface MyInterface
{
IData GetData(Input p1);
}
现在,您可能需要添加可选的细节,如bool和DateTime。因为它们是可选的,所以不必在构造函数中强制它。您仍然可以拥有相同的构造函数,并授予用户在需要时在构造函数外部进行修改的权限
class Input {
string p1; char p2; double p3; bool p4; DateTime p5;
public Input(string p1, char p2, double p3){
}
}
接口仍然可以是相同的。正如我所说的,产生这类东西的动力很不幸地取决于你的模型。简而言之,如果一个分组可以表示某种东西,使它成为一个类或接口(取决于谁将控制逻辑)。< /P>听起来有一个好主意,可以有一个参数类型的接口,但是考虑到接口不能被版本化,如果API将扩展,那么没有人可以添加更多的功能(比如说增加一个参数)。在不破坏现有代码的情况下,将其转换为参数类型。