Программирование на интерфейсе только с одним классом, реализующим указанный интерфейс - PullRequest
3 голосов
/ 22 мая 2011

Я могу понять, почему нужно программировать с использованием интерфейса, а не реализации. Однако в примере, подобном следующему (я нахожу это много):

public interface ISomething
{
    void BlahOne(int foo);
    void BlahTwo(string foo);
}

public class BaseSomething : ISomething
{
    public void BlahOne(int foo)
    {
        //impl 
    }

    public void BlahTwo(string foo)
    {
        //impl
    }
}

public class SpecificSomethingOne : BaseSomething
{
    public void SpecificOne()
    {
        //blah
    }
}

public class SpecificSomethingTwo : BaseSomething
//and on..

Текущий пример этого - система сущностей на основе компонентов в моей игре. (У меня есть IComponent, Component, PosComponent и т. Д.).

Однако я не вижу причины иметь что-то. Название может выглядеть лучше, но, похоже, у него нет цели. Я могу просто вернуть BaseSomething все время.

Есть ли причина иметь интерфейс, когда у вас есть единственная базовая реализация, которую все используют? (Я вижу использование, скажем, IComparable или IEnumerable)

РЕДАКТИРОВАТЬ: Для немного другого сценария (но все еще достаточно связанного, чтобы не нуждаться в другом вопросе), если я предполагаю, что у меня есть эта структура для всего, была бы большая разница, если бы я использовал ISomething для типов параметров и переменные по сравнению с BaseSomething?

Ответы [ 4 ]

13 голосов
/ 22 мая 2011

Я предпочитаю "ленивый дизайн" - извлекайте интерфейс из BaseSomething, когда вам это нужно. А пока, будь проще и пропусти это.

Прямо сейчас я могу думать о двух причинах наличия интерфейса, когда есть только одна реализация:

  • Существует еще одна фиктивная реализация для модульных тестов (т.е. есть вторая реализация, хотя и не в рабочем коде).
  • Интерфейс и реализация определены в разных библиотеках классов. Например. при использовании шаблона Model-View-Presenter представление может находиться в проекте .exe, который зависит от .dll, в которой реализован презентатор. Затем в .dll можно вставить интерфейс IView и ссылку докладчика на представление, предоставленное посредством внедрения зависимости.
2 голосов
/ 22 мая 2011

Правильный ответ на ваш вопрос будет " Это зависит ".

Вы можете смотреть на это по-разному, и все дело в перспективе. Когда у вас есть конкретный или абстрактный базовый класс, это означает, что ваши объекты имеют что-то общее функционально. И производные объекты так или иначе связаны между собой. Интерфейсы позволяют подтвердить функциональный контракт только в том случае, если за реализацию будет отвечать каждый объект, реализующий интерфейс.

Опять же, когда вы снова программируете интерфейсы, вы строго знаете возможности объекта, поскольку он реализует данный интерфейс. И вам не нужно беспокоиться о том, как каждый объект функционально реализует это.

Это не было бы совершенно неправильно, если бы я сказал каждый из ваших объектов полностью независимо, когда дело доходит до реализации интерфейса ISomething, учитывая, что SpecificSomethingOne и SpecificSomethingTwo не являются производными от BaseSomeThing и каждый реализует свой собственный ISomething.

Вы можете обратиться к этому ответу по тому же вопросу.

1 голос
/ 22 мая 2011

это на самом деле не нужно, но лучше, если вы хотите расширить свою программу позже или внедрить другой базовый класс.В вашем случае я бы не реализовал Базовый класс.Интерфейс только хорошо, если вы не хотите иметь поведение по умолчанию.Если вы хотите поведение по умолчанию, просто напишите базовый класс без интерфейса

0 голосов
/ 22 мая 2011

Если ваше BaseSomething было абстрактным, и у вас были реализованы определенные вещи, которые поставщик перегружал абстрактными методами, единственным способом программирования для них в этот момент был бы интерфейс ISomething. Однако в приведенном вами примере действительно нет причин для ISomething, если у вас не может быть нескольких базовых реализаций.

...