[英]Would using optional parameters in a repository interface be considered bad design?
I have created two classes to externally control page number ( Page
) and ordering ( Order
) on a repository. 我创建了两个类来外部控制存储库中的页码(
Page
)和排序( Order
)。 The repository exposes IEnumerable<T>
and not IQueryable<T>
since I want the repository to have strong testability. 存储库公开
IEnumerable<T>
而不是IQueryable<T>
因为我希望存储库具有强大的可测试性。
Say, for example, if I had the following repository: 比方说,如果我有以下存储库:
interface IUserRepository
{
public IEnumerable<User> GetAll();
}
If I want the caller to control the subset of the response, they would need to pass in the page/order. 如果我希望调用者控制响应的子集,他们需要传入页面/顺序。 So first thought would be to add overloads:
所以首先想到的是添加重载:
interface IUserRepository
{
IEnumerable<User> GetAll();
IEnumerable<User> GetAllOrderedAndPaged(Order order, Page page);
}
The problem I find with this is that I have to create multiple overloads which I find to be pretty tedious. 我发现这个问题是我必须创建多个重载,我发现这些重载非常繁琐。
What I'm thinking (but not sure) of doing is having Order
and Page
be optional parameters: 我正在考虑(但不确定)做的是将
Order
和Page
作为可选参数:
interface IUserRepository
{
IEnumerable<User> GetAll(Order order = null, Page page = null);
}
This way the calling code can easily sort/page, but not play with the main query (which is what I'm trying to avoid by exposing IEnumerable<T>
instead of IQueryable<T>
). 这样调用代码可以轻松排序/分页,但不能使用主查询 (这是我试图通过暴露
IEnumerable<T>
而不是IQueryable<T>
来避免)。
Does this seem like a good or bad design? 这看起来像一个好的或坏的设计? I know that could be considered a bit subjective, but I'm trying to see if there is functionally wrong with this.
我知道这可能被认为有点主观,但我试图看看这是否存在功能上的错误。 The main key is that my repositories are testable and the caller can't play around/change the query too much.
主要的关键是我的存储库是可测试的,并且调用者无法使用/更改查询太多。 I figured that since sorting/ordering are a very common task for a returning set of data, why not incorporate them into the design of the repository interface.
我认为,由于排序/排序是返回数据集的一个非常常见的任务,为什么不将它们合并到存储库接口的设计中。 Again, when testing, I only care that the right set of data is returned, but the caller can say "Now, give me this page/ordered subset of the data".
再次,在测试时,我只关心返回正确的数据集,但调用者可以说“现在,给我这个页面/有序的数据子集”。
I would caution against using optional parameters since the default values will be compiled into the caller. 我会提醒您不要使用可选参数,因为默认值将被编译到调用者中。 This means that if the default values ever change, any code that uses the original default values will need to be recompiled.
这意味着如果默认值发生变化,则需要重新编译使用原始默认值的任何代码。
This could be a problem in your specific example if, in the future, you decided that null
wasn't a valid value, changed the defaults, and started throwing a ArgumentNullException
if null
was passed in. Any code that uses your interface will have to recompiled or potentially start throwing ArgumentNullExceptions
. 如果将来确定
null
不是有效值,更改了默认值,并且如果传入null
则开始抛出ArgumentNullException
,这可能是您的特定示例中的问题。任何使用您的接口的代码都必须重新编译或可能开始抛出ArgumentNullExceptions
。
You can read a much better explanation of this here and here . 你可以在这里和这里阅读更好的解释。
The key take-away from this: once you expose a default parameter value on a public method, you can never change it without recompiling all clients that depend on it.
关键是:在公共方法上公开默认参数值后,如果不重新编译依赖于它的所有客户端,就永远不能更改它。 For library writers, this never means never ever .
对于图书馆作家来说,这绝不是永远不会的 。
I've decided to use both parameters as properties on the repository itself. 我决定将这两个参数用作存储库本身的属性。 Taking into consideration the fact that the default value will be compiled into the caller, but also the fact that writing these parameters on every method on every possible repository could be tedious.
考虑到默认值将被编译到调用者中的事实,以及在每个可能的存储库上的每个方法上写这些参数的事实可能是乏味的。
For my style of programming with a lot of lambda's optional parameters are not well suitable. 对于我的编程风格,有很多lambda的可选参数都不太合适。
C# 4.0 Features – Named & Optional Parameters – Uh, no thanks: http://blogs.ijw.co.nz/chris/index.php/2010/05/c-4-0-features-named-optional-parameters-uh-no-thanks/ C#4.0功能 - 命名和可选参数 - 呃,不,谢谢: http : //blogs.ijw.co.nz/chris/index.php/2010/05/c-4-0-features-named-optional-parameters-嗯,没有,谢谢/
As a better design I would use a tuple as parameter. 作为一个更好的设计,我会使用元组作为参数。 Or named class that aggregate page and order with default fields values.
或命名类,使用默认字段值聚合页面和顺序。 Sorry it's of course subjective.
对不起,这当然是主观的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.