简体   繁体   English

在存储库接口中使用可选参数会被视为糟糕的设计吗?

[英]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: 我正在考虑(但不确定)做的是将OrderPage作为可选参数:

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.

相关问题 基于接口的设计和可选的方法参数 - Interface based design and optional method parameters 创建方法“模板”(通过将某些方法传递给模板方法)会被认为是不良设计吗? - Would creating a method “template” (by passing some method to the template method) be considered bad design? 在构造函数中进行冗长的操作会被认为是不好的设计吗? - Is it considered bad design to do lengthy operations in a constructor? 为什么在依赖解析期间不考虑可选的构造函数参数 - Why are optional constructor parameters are not considered during dependency resolution 继承:为什么更改对象的类型被认为是糟糕的设计? - Inheritance: why is changing an object's type considered bad design? 为什么是“使用系统”; 不被认为是不好的做法? - Why is "using System;" not considered bad practice? 可以访问存储库中的UnitOfWork是不好的设计吗? - Is it bad design to have access to the UnitOfWork in the Repository? 显式实现带有可选参数的接口的警告 - Warning From Explicitly Implementing an Interface with Optional Parameters 是否有任何理由在接口中声明可选参数? - Is there any reason to declare optional parameters in an interface? 使用通用接口存储库 - Using generic interface repository
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM