添加参数,还是创建新方法?

时间:2011-03-23 17:44:55

标签: c# oop design-patterns

假设我有一个长期建立的存储库,如下所示:

interface IDonutRepository
{
    public IEnumerable<Donut> GetDonuts();
}

它已经存在了很长时间,GetDonuts方法完成了它的说法。然后有一天我需要添加一个显示数据库中所有甜甜圈的新屏幕,结果发现该方法有一个隐藏的功能 - 它会过滤掉所有甜甜圈stale = true。但是在我的新屏幕上,我想展示所有这些,甚至是陈旧的!这里最好的方法是什么?

假设这个方法在所有地方都被使用,并且默认行为需要保持不变,最好添加一个名为GetAllDonuts的新方法,该方法不进行过滤,或者我应该只是在onlyFresh方法上添加GetDonuts参数?

我猜它只是判断力,但我想知道那里是否有更明智的答案?

5 个答案:

答案 0 :(得分:9)

我会重载该方法,创建一个新的重载,该重载采用showStale参数,然后修改旧方法以使用新的重载传递false作为参数值。

界面如下:

interface IDonutRepository
{
    public IEnumerable<Donut> GetDonuts();
    public IEnumerable<Donut> GetDonuts(bool showStale);
}

或者,如果您使用的是.NET 4.0,则可以使用可选参数:

interface IDonutRepository
{
    public IEnumerable<Donut> GetDonuts(bool showStale = false);
}

答案 1 :(得分:2)

为什么不使用可选参数?这样您就不会破坏现有代码:

interface IDonutRepository
{
    public IEnumerable<Donut> GetDonuts(bool onlyFresh);
}

实现:

public IEnumerable<Donut> GetDonuts(bool onlyFresh = false)
{
    if (onlyFresh)
        // do stuff
    else
        // do other stuff
}

答案 2 :(得分:1)

这在某种程度上归结为个人偏好......

如果您能够更改API,我会(个人)重命名当前方法,使其显然不会返回所有Donut个实例。我的期望是存储库的GetDonuts方法将获得所有的甜甜圈。这可以通过参数或不同的名称来自行决定。

话虽如此,如果保持兼容性至关重要,那么采用额外参数的方法过载可能是向前发展的最佳选择。 (这很大程度上取决于使用此API的人和位置......)

答案 3 :(得分:1)

根据环境的不同,人们可能会考虑引入一个用于访问甜甜圈的财产。

interface IDonutRepository
{
    IEnumerable<Donut> Donuts { get; }
    .. or ..
    IQueryable<Donut> Donuts { get; }
}

如果您正在使用像Entity Framework或NHibernate这样的Linq-savvy ORM,那么实现此接口相当容易。

旧的GetDonuts方法可以重命名为GetFreshDonuts(),或者您可以将对它的调用重构为以下格式:

repository.Donuts.Where(x => !x.Stale)

答案 4 :(得分:0)

  

软件发展趋势之一   设计是分离界面   实现。原则是关于   将模块分成公共和   私人部分,以便你可以改变   没有协调的私人部分   与其他模块。但是,有   进一步的区别 - 两者之间的区别   公共和已发布的接口。这个   区别很重要因为它   影响你如何使用   接口

http://www.martinfowler.com/ieeeSoftware/published.pdf