繁体   English   中英

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

[英]Would using optional parameters in a repository interface be considered bad design?

我创建了两个类来外部控制存储库中的页码( Page )和排序( Order )。 存储库公开IEnumerable<T>而不是IQueryable<T>因为我希望存储库具有强大的可测试性。

比方说,如果我有以下存储库:

interface IUserRepository
{
    public IEnumerable<User> GetAll();
}

如果我希望调用者控制响应的子集,他们需要传入页面/顺序。 所以首先想到的是添加重载:

interface IUserRepository
{
    IEnumerable<User> GetAll();
    IEnumerable<User> GetAllOrderedAndPaged(Order order, Page page);
}

我发现这个问题是我必须创建多个重载,我发现这些重载非常繁琐。

我正在考虑(但不确定)做的是将OrderPage作为可选参数:

interface IUserRepository
{
    IEnumerable<User> GetAll(Order order = null, Page page = null);
}

这样调用代码可以轻松排序/分页,但不能使用主查询 (这是我试图通过暴露IEnumerable<T>而不是IQueryable<T>来避免)。

这看起来像一个好的或坏的设计? 我知道这可能被认为有点主观,但我试图看看这是否存在功能上的错误。 主要的关键是我的存储库是可测试的,并且调用者无法使用/更改查询太多。 我认为,由于排序/排序是返回数据集的一个非常常见的任务,为什么不将它们合并到存储库接口的设计中。 再次,在测试时,我只关心返回正确的数据集,但调用者可以说“现在,给我这个页面/有序的数据子集”。

我会提醒您不要使用可选参数,因为默认值将被编译到调用者中。 这意味着如果默认值发生变化,则需要重新编译使用原始默认值的任何代码。

如果将来确定null不是有效值,更改了默认值,并且如果传入null则开始抛出ArgumentNullException ,这可能是您的特定示例中的问题。任何使用您的接口的代码都必须重新编译或可能开始抛出ArgumentNullExceptions

你可以在这里这里阅读更好的解释。

关键是:在公共方法上公开默认参数值后,如果不重新编译依赖于它的所有客户端,就永远不能更改它。 对于图书馆作家来说,这绝不是永远不会的

我决定将这两个参数用作存储库本身的属性。 考虑到默认值将被编译到调用者中的事实,以及在每个可能的存储库上的每个方法上写这些参数的事实可能是乏味的。

对于我的编程风格,有很多lambda的可选参数都不太合适。

C#4.0功能 - 命名和可选参数 - 呃,不,谢谢: http //blogs.ijw.co.nz/chris/index.php/2010/05/c-4-0-features-named-optional-parameters-嗯,没有,谢谢/

作为一个更好的设计,我会使用元组作为参数。 或命名类,使用默认字段值聚合页面和顺序。 对不起,这当然是主观的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM