Шаблон разработки стратегии С# от делегата против OOP
Интересно, какие плюсы и минусы использования делегирования против OOP при реализации шаблона стратегии разработки?
Какой из них вы рекомендуете использовать? или какая проблема решает делегат? и почему мы должны использовать ООП, если ООП лучше?
Спасибо!
-tep
Ответы
Ответ 1
Оба метода могут быть мощными и ценными - вот некоторые из моих мнений о том, когда их использовать.
Используйте подход "Интерфейс/Реализация", когда стратегия:
- поддерживает состояние
- требуется конфигурация
- использует инъекцию зависимостей
- должен быть настроен контейнером IoC (подумайте ConnectionProvider)
- объединяет несколько обязанностей (думаю, DataAdapter от ADO.NET)
- слишком сложный или длинный, как единственный метод
- вероятно, будет подклассифицирован для создания новых стратегий
- необходимо вернуть информацию о состоянии вызывающему абоненту
- должен иметь доступ к внутренностям объекта, относится к
- Требуется слишком много прямых параметров
В противном случае, как правило, используются делегаты на основе Func < > или Action < > , особенно если
- Скорее всего, существует очень большое разнообразие стратегий (выражения выражения выражений)
- Стратегия лучше всего выражается как лямбда
- Существует существующий метод, который вы хотите использовать
Ответ 2
В пользу делегатов:
- Делегирование проще реализовать в легком режиме с использованием лямбда-выражений и динамических методов
- Делегаты могут быть созданы из "нормальных" методов с правильной подписью
- Делегирование, являющееся многоликим, может быть полезно время от времени (хотя относительно редко за пределами события)
В пользу интерфейсов:
- Объект может реализовать интерфейс и выполнять другие действия: делегат - это просто делегат
- Интерфейс может иметь несколько методов; у делегата есть только
Может идти в любом случае:
- С интерфейсами вы получаете два имени: интерфейс и метод. С делегатами у вас есть только один. Часто я нахожу, что интерфейсы одного метода повторяют одно и то же имя дважды (с вариантами) или имя метода очень мягкое
Лично я большой поклонник делегатов за их гибкость, но это действительно зависит от ситуации.
Ответ 3
На мой взгляд, если вы используете делегатов, вы фактически не реализуете шаблон стратегии. Вы на самом деле реализуете нечто более похожее на шаблон наблюдателя. Весь смысл шаблонов дизайна заключается в том, что когда вы говорите: "Я использовал шаблон стратегии здесь", у каждого есть много контекста на том, что вы сделали. Когда вы начинаете говорить такие вещи, как "Я использовал шаблон стратегии, кроме как с моими собственными модификациями", тогда все становится рискованным.
Но, если я понимаю, что вы пытаетесь сказать, одна из приятных особенностей шаблона стратегии, которая не так понятна для делегатов, - это иерархия объектов, реализующих стратегию.
Скажем, что я тестирую часть программного обеспечения. Я хочу проверить его с помощью мыши и с помощью клавиатуры. Поэтому я смогу применить шаблон стратегии, чтобы подключить метод интерфейса для использования в каждом тестовом случае... поэтому я могу написать тестовый пример один раз и полностью запустить его с помощью MouseStrategy и KeyboardStrategy. Оттуда я могу реализовать специализации, такие как MouseExceptForDialogsStrategy, специализация MouseStrategy. Такая иерархия, как ее расширить и переопределить, легко понять кто-нибудь, знакомый с концепциями ООП... тогда как как добиться и расширить то же с делегатами гораздо сложнее и гораздо более неясным.
Как и во многих вещах... это не вопрос "можете ли вы это сделать?", но "если вы это сделаете?".
Ответ 4
Мне нравится использовать интерфейс для абстрагирования моей стратегии. Затем у моих конкретных реализаций есть видимый файл для каждой стратегии. При работе с классом вместо метода он дает вам большую гибкость. Я могу использовать Rhino mocks для издевательства над стратегией, чтобы протестировать ее. Я также могу легко использовать рамки DI, такие как Ninject, чтобы очень просто связывать приложение стратегии. Я использую делегаты для извлечения реализации в основном в диалоговых окнах WinForm.
Ответ 5
Согласно этому сообщению в блоге Pluralsight:
Основное различие между делегатами и интерфейсами состоит в том, что, хотя делегаты уменьшают базу кода и повышают читабельность кода, вы должны быть осторожны с тем, как вы их используете, иначе вы можете в конечном итоге пожертвовать тестируемостью. Кодирование интерфейсов обычно более надежно, даже если для этого требуется больше кода