Что лучше передать * interface * или * object * в качестве параметра функции? - PullRequest
6 голосов
/ 16 июня 2009

Я пытаюсь убедить коллегу, что функция должна принимать интерфейс в качестве параметра, а не сам объект. Я думаю, что небольшие объекты могут быть хорошими для передачи, но для больших я бы дал им интерфейс и просто передал бы I / F, а не все.

Обратите внимание, что когда-либо будет только один из этих больших классов - i / f никогда не будет использоваться для другого объекта. Это просто для сокрытия реализации объекта.

Согласны ли вы с тем, что разделение большого класса на интерфейс (ы) является хорошей практикой?
Есть ли недостатки в этом?

Пример:

public interface class IVeryLargeClass
{
    void DoSomething();
    ...
};

public ref class VeryLargeClass : public IVeryLargeClass
{
public:
    virtual void DoSomething() { ... }
    ...
};

public ref class AnotherClass
{
public:
    AnotherClass(VeryLargeClass^ vlc)  { vlc->DoSomething(); }
 // OR
    AnotherClass(IVeryLargeClass^ vlc) { vlc->DoSomething(); }
};

Ответы [ 5 ]

12 голосов
/ 16 июня 2009

Один из первых принципов, которые вы изучаете при разработке ОО:

Программа для интерфейса, а не осуществление.

Вы указываете, что "когда-либо будет только один из этих больших классов - i / f никогда не будет использоваться для другого объекта". Это может быть правдой в вашем случае, но мне бы хотелось, чтобы у меня был никель на каждый раз, когда такое утверждение оказывалось неверным.

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

Проще говоря, интерфейсы предоставляют средства для управления связью между клиентами и поставщиками.

8 голосов
/ 16 июня 2009

Принцип инверсии зависимостей можно суммировать следующим образом: лучше полагаться на абстракции, чем на конкреции.

Почти всегда лучше передать интерфейс, чем передать конкретный класс.

Тем не менее, высокая способность связываться с внутренними типами в пределах определенного модуля приемлема, но это очень субъективно в отношении того, когда и как вы должны передавать конкретные объекты.

3 голосов
/ 16 июня 2009

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

3 голосов
/ 16 июня 2009

Если вы пропустите реализацию, вы потеряете одно из преимуществ использования интерфейсов, то есть отделите логику от фактической реализации.

Интерфейс программного модуля A намеренно хранится отдельно от реализация этого модуля. последний содержит фактический код процедуры и методы, описанные в интерфейс, а также другие «частные» переменные, процедуры и т. д. Любой другой программный модуль B (который может называться клиентом для A), что взаимодействует с А вынужден сделать это только через интерфейс. Один практическое преимущество этого договоренность о том, что замена реализация А другим что соответствует тем же спецификациям интерфейс не должен вызывать B к терпеть неудачу - до тех пор, пока его использование А соответствует со спецификациями интерфейс (см. также Лисков принцип замещения).

http://en.wikipedia.org/wiki/Interface_(computer_science)

1 голос
/ 17 июня 2009

Другая проблема - это ваш очень большой класс. Это может не входить в рамки того, что вы делаете, но очень большой класс подразумевает, что он может делать слишком много в первую очередь. Можете ли вы преобразовать его в меньший класс, где информация, требуемая в вызываемой функции, инкапсулирована в ее собственный меньший класс? Если вы создадите интерфейс для этого класса, вы можете найти его гораздо более пригодным для повторного использования, чем для очень большого класса, который у вас есть в настоящее время.

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