我将 API 定义为我们将调用的接口,IFoo
并且我想定义一个方法Bar()
此方法Bar()
将采用一个必需的参数,然后采用任意数量的其他参数。这些其他论点的解释将取决于实现者IFoo
params
对于这种情况,使用或使用Dictionary<String, Object>
例如定义我的界面是否更合适
public interface IFoo
{
bool Bar(String id, params Object[] params);
}
或者
public interface IFoo
{
bool Bar(String id, Dictionary<String, Object> params);
}
似乎前者对用户来说更容易调用,但后者的意图更明确,因为对于前者,您必须以特定顺序指定参数,以便实现正确解释它们,而对于后者,您本质上是做命名参数。
所以问题:
- 我应该使用哪种形式(以及为什么?) - 其中一种被认为是最佳实践而不是另一种?
- 一种风格与另一种风格相比是否有我应该注意的特定优势?其中之一是否被认为是代码异味?
- 是否有另一种模式可以以不同/更好的方式实现相同的目标?
作为记录,我知道 .Net 4.0 中的命名参数,但此代码需要在 .Net 3.5 上编译,因此不能使用任何 .Net 4.0+ 功能
编辑
只是为了添加更多关于我IFoo
和Bar()
方法实际代表的细节,因为有人问过。
IFoo
代表一些存储子系统,Bar()
实际上是一个创建操作。取决于存储子系统Bar()
,可能不需要除 ID 以外的参数,也可能需要许多参数。
编辑 2
因此,为了回应@Kirk Woll 的评论和@Fernando 的回答,这里有更多信息。
我可能永远不会调用IFoo.Bar()
自己,这个接口是开源框架的一部分。3rd 方开发人员将实施IFoo
,最终用户将调用它的特定实例,这样做的IFoo
目的是让用户更容易在存储子系统之间迁移他们的应用程序,因为他们可以编码到接口而不是特定实现,只要人为可能。
在最简单的情况下,底层存储子系统只有一种形式的存储,因此除了 ID 之外不需要其他参数。在复杂的情况下,存储子系统可以允许多种类型的存储,并且每种类型的存储可以允许任意复杂的配置参数集,例如索引大小、持久性、事务行为、索引策略、安全性和 ACL 考虑等。
我同意@Fernando 的观点,也许更多的多态性可能是有意义的,也许多态性与泛型和类型限制相结合可能是最好的,例如
public interface IFoo
{
bool Bar<T>(T parameters) where T : IBarConfig;
}
public interface IBarConfig
{
String ID { get; set; }
}
然后使用这样的实现:
public class MyFoo
{
bool Bar<T>(T config) where T : MyBarConfig
{
//Implementation
}
}
public class MyBarConfig : IBarConfig
{
public String ID { get; set; }
public long IndexSegmentSize { get; set; }
//Etc...
}
这不是我的想法,所以不确定用不同的类型限制定义是否真的合法,Bar()
然后MyFoo
是它实现的接口?