События против переопределенных методов? - PullRequest
10 голосов
/ 31 июля 2011

Может ли кто-нибудь дать мне общие рекомендации относительно того, когда мне следует использовать переопределяемые методы, такие как «OnMyEvent», и когда мне следует использовать такие события, как «MyEvent» в C #?

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

Ответы [ 2 ]

7 голосов
/ 31 июля 2011

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

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

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

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

  • Кто вызвал это: Произойдет ли действие, которое запускает ваш переход состояния внутри, или оно будет вызвано извне?

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

  • Кого это волнует: Должен ли класс, определяющий состояние, обрабатывать последствия перехода состояния или внешний класс должен его обрабатывать?

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

  • Сколько обработчиков мне нужно: Вам всегда нужен один обработчик, чтобы реагировать на изменение состояния, или вам нужно много?

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

  • Знаю ли я, какой обработчик мне нужен во время компиляции: Связываюсь ли я с одним известным обработчиком или я связываюсь с неизвестными обработчиками, возможно меняющимися со временем?

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

  • Насколько связан должен быть мой код: Принадлежит ли ваш код обработчика производному классу вашего исходного типа или он принадлежит другому месту?

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

Как видите, ответы будут сильно зависеть от конкретной предметной области и архитектуры объекта. Хороший дизайн - это не то, что волшебным образом попадает к вам на колени через какой-то контрольный список. Надо много думать об этом:)

Edit:

Возможно, это не относится напрямую к событиям C #, но может быть полезно взять пример из существующей работы. Вот краткая статья, которую я только что нашел (отвечая на другой вопрос) об альтернативах проектирования в Java для шаблонов событий: http://csis.pace.edu/~bergin/patterns/event.html

6 голосов
/ 31 июля 2011

События отлично подходят для случаев, когда у вас есть «имеет», в то время как переопределения намного лучше для ситуаций, где у вас есть отношение «есть»

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

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

...