Добавить параметр или создать новый метод? - PullRequest
4 голосов
/ 23 марта 2011

Допустим, у меня есть давно установленный репозиторий, подобный этому:

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

Он существует целую вечность, и метод GetDonuts делает то, что говорит.Затем однажды мне нужно добавить новый экран, который показывает все пончики в базе данных, и оказывается, что метод имеет скрытую функцию - он отфильтровывает все пончики, где stale = true.Но на моем новом экране я хочу показать их все, даже устаревшие!Какой здесь лучший подход?

Предполагая, что этот метод используется повсеместно, а поведение по умолчанию должно оставаться прежним, лучше всего добавить новый метод с именем GetAllDonuts, который невыполнять фильтрацию, или я должен просто добавить параметр onlyFresh в метод GetDonuts?

Я предполагаю, что это просто решение, но мне интересно, есть ли какие-либо более информированные ответы изесть

Ответы [ 5 ]

9 голосов
/ 23 марта 2011

Я бы перегрузил метод, создав новую перегрузку, которая принимает параметр 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);
}
2 голосов
/ 23 марта 2011

Почему бы не использовать необязательный параметр?Таким образом, вы не нарушаете существующий код:

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

Реализация:

public IEnumerable<Donut> GetDonuts(bool onlyFresh = false)
{
    if (onlyFresh)
        // do stuff
    else
        // do other stuff
}
1 голос
/ 23 марта 2011

В зависимости от обстоятельств можно рассмотреть вопрос о введении собственности для доступа к пончикам.

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

Реализовать этот интерфейс довольно просто, если вы используете сообразительный ORM Linq, такой как Entity Framework или NHibernate.

Старый метод GetDonuts может быть переименован в GetFreshDonuts (), или вы можете изменить его вызовы в виде:

repository.Donuts.Where(x => !x.Stale)
1 голос
/ 23 марта 2011

Это действительно сводится к личным предпочтениям, в некоторой степени ...

Если у вас есть возможность изменить API, я бы (лично) переименовал текущий метод таким образом, чтобы было очевидно, что он не возвращает все Donut экземпляры. Я ожидал бы, что метод репозитория GetDonuts получит все пончики. Это может быть сделано с помощью параметра или другого имени по вашему усмотрению.

При этом перегрузка метода, принимающая дополнительный параметр, вероятно, является наилучшим вариантом для продвижения вперед, если важно обеспечить совместимость. (Это во многом зависит от того, кто и где использует этот API ...)

0 голосов
/ 23 марта 2011

Одной из растущих тенденций в разработке программного обеспечения является отделение интерфейса от реализации.Принцип заключается в разделении модулей на открытые и закрытые части, чтобы вы могли изменить приватную часть без координации с другими модулями.Тем не менее, существует еще одно различие - между публичными и опубликованными интерфейсами.Это различие важно, потому что оно влияет на то, как вы работаете с интерфейсом.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...