我将API定义为一个接口,我们将其称为
这个方法
对于这种情况,使用
似乎前者更容易被用户调用,但后者在意图上更加明确,因为使用前者需要按特定顺序指定参数才能使实现正确解释它们,而使用后者则基本上是在使用命名参数。
所以问题是:
我可能永远不会自己调用
在最简单的情况下,底层存储子系统只有一种形式的存储,因此除ID外不需要任何参数。在复杂情况下,存储子系统可以允许多种类型的存储,每种类型的存储都可以允许任意复杂的配置参数集,例如索引大小、持久性、事务行为、索引策略、安全性和ACL考虑等。
然后使用以下实现方式:
这只是我脑海中的想法,不确定在
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);
}
似乎前者更容易被用户调用,但后者在意图上更加明确,因为使用前者需要按特定顺序指定参数才能使实现正确解释它们,而使用后者则基本上是在使用命名参数。
所以问题是:
- 我应该使用哪种形式(以及为什么)-其中一种被认为比另一种最佳实践吗?
- 是否有特定的优势,使一种风格比另一种更好?其中一种被视为代码异味吗?
- 是否有一种替代模式可以以不同/更好的方式实现相同的事情?
编辑
只是添加关于我的IFoo
和Bar()
方法实际表示的更多细节,因为有人问过。
IFoo
代表某个存储子系统,Bar()
实际上是一个创建操作。根据存储子系统,Bar()
可能只需要ID等少量参数,也可能需要很多参数。
编辑2
为了回应@Kirk Woll的评论和@Fernando的答案,这里提供更多信息。我可能永远不会自己调用
IFoo.Bar()
,因为这个接口是开源框架的一部分。第三方开发人员将实现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...
}
这只是我脑海中的想法,不确定在
MyFoo
中定义Bar()
时,使用与其实现的接口不同的类型限制是否合法?
IFoo
的哪个实现以决定传递什么类型的参数到Bar
,那么您可能使用了错误的抽象。调用IFoo
的程序应该对实现是不加考虑的,但是您的设计却相反。在更复杂的情况下需要传递哪些参数?也许这些参数应该作为实现的属性而不是方法的参数。 - Kirk Woll