Шаблон проектирования стратегии C # делегатом против ООП - PullRequest
25 голосов
/ 12 июня 2009

Интересно, в чем плюсы и минусы использования делегата против ООП при реализации шаблона проектирования стратегии?

Какой из них вы рекомендуете использовать? или какую проблему делегат решает? и почему мы должны использовать ООП, если ООП лучше?

Спасибо!

-tep

Ответы [ 5 ]

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

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

Используйте подход Интерфейс / Реализация, когда стратегия:

  1. поддерживает состояние
  2. нужна конфигурация
  3. использует внедрение зависимостей
  4. должен быть настроен контейнером IoC (подумайте ConnectionProvider)
  5. сочетает в себе несколько обязанностей (например, DataAdapter из ADO.NET)
  6. слишком сложный или длинный, как один метод
  7. может быть разделен на подклассы для создания новых стратегий
  8. необходимо вернуть информацию о состоянии вызывающей стороне
  9. необходимо для доступа к внутренним объектам относится к
  10. Требуется слишком много прямых параметров

В противном случае, как правило, используйте делегатов на основе Func <> или Action <>, особенно если

  1. Вероятно, существует очень большое разнообразие стратегий (подумайте о выражениях сортировки)
  2. Стратегия лучше всего выражается как лямбда
  3. Существует существующий метод, который вы хотите использовать
16 голосов
/ 12 июня 2009

В пользу делегатов:

  • Делегатов проще реализовать легким способом, используя лямбда-выражения и динамические методы
  • Делегаты могут быть созданы из "обычных" методов с правильной подписью
  • Делегаты, являющиеся многоадресными , могут быть полезными время от времени (хотя относительно редко вне событий)

В пользу интерфейсов:

  • Объект может реализовать интерфейс и выполнять другие действия: делегат просто делегат
  • Интерфейс может иметь несколько методов; у делегата только один

Может пойти в любом направлении:

  • При использовании интерфейсов вы получаете два имени: интерфейс и метод. С делегатами у вас есть только один. Часто я нахожу, что интерфейсы с одним методом либо повторяют одно и то же имя дважды (с вариациями), либо имя метода очень мягкое

Лично я большой поклонник делегатов за их гибкость, но это действительно зависит от ситуации.

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

По моему мнению, если вы используете делегатов, то на самом деле вы не реализуете шаблон Стратегия . На самом деле вы реализуете что-то более похожее на Observer pattern . Весь смысл шаблонов проектирования заключается в том, что когда вы говорите: «Я использовал шаблон« Стратегия »», у всех появляется много контекста в том, что вы сделали. Когда вы начинаете говорить что-то вроде «Я использовал шаблон Стратегии, за исключением своих личных изменений», все становится рискованным.

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

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

Как и во многих вещах ... вопрос не в том, «можете ли вы это сделать?», А в том, «стоит ли вам это делать?».

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

Мне нравится использовать интерфейс для абстрагирования моей стратегии. Мои конкретные реализации имеют видимый файл для каждой стратегии. При работе с классом вместо метода это дает вам больше гибкости. Я могу использовать насмешки Rhino, чтобы смоделировать стратегию, чтобы проверить ее. Я также могу легко использовать DI-фреймворки, такие как Ninject, чтобы очень легко связать приложение стратегии. Я использую Делегаты для извлечения реализации в основном из диалогов WinForm.

0 голосов
/ 25 апреля 2019

Согласно этому Pluralsight сообщение в блоге :

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

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