Когда вам нужно создавать абстракции в виде интерфейсов? - PullRequest
4 голосов
/ 23 февраля 2010

Когда вы поощряете программирование для интерфейса, а не для конкретного класса?

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

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

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

Я что-то упустил?

Ответы [ 6 ]

6 голосов
/ 23 февраля 2010

Кроме того, используйте интерфейсы, когда

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

  • Передача интерфейсов в качестве параметров может быть очень полезна при модульном тестировании. Даже если у вас есть только один тип объекта, который поддерживает определенный интерфейс, и, следовательно, на самом деле не нужен определенный интерфейс, вы можете определить / реализовать интерфейс исключительно для " fake " этого объекта в модульных тестах.

  • , относящихся к первым двум пунктам, посмотрите Наблюдательский паттерн и Внедрение зависимостей . Я не говорю, чтобы реализовать эти шаблоны, но они иллюстрируют типы мест, где интерфейсы действительно полезны.

  • Еще одна особенность заключается в реализации пары принципов SOLID: Открыто-закрытый принципал и Принцип разделения интерфейсов . Как и в предыдущем пункте, не беспокойтесь о строгом соблюдении этих принципов повсюду (по крайней мере, сразу), но используйте эти концепции, чтобы помочь отвлечь ваше мышление от всего лишь того, какие объекты идут куда , до размышлений о контракты и зависимость

  • В конце, давайте не будем усложнять ситуацию: мы находимся в строго типизированном мире .NET. Если вам нужно вызвать метод или установить свойство, но передаваемый / используемый вами объект может существенно отличаться, используйте интерфейс.

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

1 голос
/ 23 февраля 2010

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

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

Кроме того, интерфейсы очень часто оказываются полезными для составных объектов. Это единственный способ, как что-то вроде библиотеки свингов в java, но это также может быть полезно для более обыденных объектов. (Лично мне нравится иметь такой интерфейс, как ValidityChecker, с возможностью и-или-или-или-или-либо подчинять подчиненных ValidityChecker s.)

1 голос
/ 23 февраля 2010

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

Во-первых, абстракция не означает «интерфейс». например, «строка соединения» - это абстракция, даже если это просто строка ... она не о «типе» рассматриваемой вещи, а о намерении использования этой вещи.

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

1 голос
/ 23 февраля 2010

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

В будущем ваш код будет легче модифицировать, а тестирование будет проще (смоделировано).

1 голос
/ 23 февраля 2010

Интерфейсы абстракции удобны при выполнении юнит-теста. Это помогает для насмешки тестовых объектов. Это очень полезно в TDD для разработки без фактического использования данных из вашей базы данных.

0 голосов
/ 23 февраля 2010

Большинство полезных вещей, которые идут с передачей интерфейса, уже сказано. Однако я бы добавил:

  • реализуя интерфейс к объекту или более поздним множественным объектам, заставляет всех разработчиков следовать шаблону IDENTICAL для реализации контракта с объектом. Это может быть полезно в том случае, если у вас не очень опытные программисты ООП, пишущие код реализации.
  • в некоторых языках вы можете добавлять атрибуты на сам интерфейс, которые могут отличаться от фактического атрибута реализации объекта как смысл и намерение
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...