События в системе внедрения зависимостей идут в какую сторону? - PullRequest
3 голосов
/ 09 октября 2009

Вверх или вниз?

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

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

UP: (без DI?)
Должны ли мои события отправляться из низа моей иерархии и подниматься к их родителям? Например. кнопка в моем графическом интерфейсе отправляет событие CLICKED, которое перехватывается слушающим контейнером, который отвечает, выполняя соответствующее действие.

ВНИЗ: (путь DI?)
Должны ли мои события отправляться из top моей иерархии родителем, которого слушают его дети? Например. - ... хорошо, у меня возникли проблемы с этим. Я размышляю в духе посредника, который отправляет события для содержащихся объектов.

Мне кажется, что «Вверх» естественно, но поскольку у DI есть контейнер, который не знает о поведении содержащихся в нем объектов, я бы не хотел отвечать на их события.

РЕДАКТИРОВАТЬ (уточнить):

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

Мой вопрос возникает из-за распределения ответственности в системе DI - ответственность за инжектируемый объект вызывает вызов инжектора и ответственность инжектора по предоставлению услуг своим зависимым объектам (что инвертирует парадигму не-DI - отсюда и синонимы как "Инверсия управления" и "Инверсия зависимости"). Кажется, это очень важный, фундаментальный компонент DI - смена обязанностей. Я считаю, что вызов функций объекта или прослушивание его событий ОБА являются примерами зависимости от другого объекта. Когда объект определяет свое собственное поведение на основе другого объекта, я называю это зависимостью, потому что один объект ЗНАЕТ другого, а также ЗНАЕТ, что делает другой. Он определил себя в контексте другого объекта. Как я понимаю, DI настроен таким образом, чтобы инжектируемый объект зависел от инжектора, поэтому именно инжектируемый объект должен знать все об инжекторе. И это не должно быть обязанностью инжектора знать о введенном объекте. Таким образом, для инжектора прослушивание событий на объекте CONTAINED кажется мне неправильным распределением обязанностей, потому что это означает, что он знает кое-что о его содержимом.

Пожалуйста, скажите мне, если и как это неправильно.

Ответы [ 6 ]

3 голосов
/ 18 октября 2009

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

Рассмотрим типичный пример, когда кнопка состоит из элемента управления. Когда кнопка нажата, она вызывает событие Clicked, на которое отвечает содержащий элемент управления. В этом случае объект наблюдения составляет объект наблюдения.

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

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

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

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

EDIT

Относительно вашего разъяснительного раздела, я полагаю, я понимаю источник вашего замешательства. Традиционно объект создает свои собственные зависимости. Внедрение зависимостей инвертирует ответственность за получение этих зависимостей, перемещая знания о том, как зависимость получается вне объекта. Однако внедрение зависимости не инвертирует отношения зависимости. Возможно, вы путаете инъекцию зависимости с принципом обращения зависимости . Принцип инверсии зависимости полностью меняет отношение зависимостей между объектами «высокого уровня» и «низкого уровня», но внедрение зависимостей касается только того, как зависимости предоставляются данному объекту. Следовательно, использование внедрения зависимостей не меняет того, как объекты обычно взаимодействуют друг с другом. Если до использования объекта внедрения зависимости B, подписанного на события, вызванные объектом A (или наоборот), введение внедрения зависимости не изменит этого.

1 голос
/ 17 октября 2009

Я говорю, что путь снизу вверх - это путь. То, что вы, вероятно, ищете, - это цепочка ответственности своего рода паттерн. События начинаются на «листьях». Лист либо обрабатывает его, либо передает его по иерархии родительскому объекту. Родительский объект листа либо обрабатывает его, либо передает его вверх по иерархии и т. Д.

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

interface IEventHandler {
    void setNextHandler(IEventHandler nextHandler);
    void handleEvent(Event e);
}
1 голос
/ 09 октября 2009

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

РЕДАКТИРОВАТЬ: Посмотрите на это визуальное описание для Наблюдатель

1 голос
/ 09 октября 2009

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

Но вы должны убедиться, что каждая часть способна обрабатывать события.

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

Я вижу, что она идет вверх, но вы не указали, как вы определяете направление.

0 голосов
/ 18 октября 2009

Как насчет передачи события аналогично привязке WPF?

0 голосов
/ 16 октября 2009

Знаете ли вы что-нибудь об архитектуре шины сообщений, например, события и запросы?

В высококонкурентных системах нижние уровни обрабатывают такие вещи, как ввод-вывод, щелчок мыши и т. Д., Которые требуют времени или операции могут быть заблокированы, например, дисковый ввод-вывод или сетевое сообщение Tx / Rx; в то время как верхние уровни всегда обрабатывают более быстрые операции, или логические вычисления, потому что верхние уровни не будут вовлечены ни в какие операции ввода-вывода и т. д. В такой системе событие - это уведомление о том, что оно уведомляет верхние слои о том, что что-то произошло. Например, пакет прибыл, или на диск была записана строка. Как только верхние слои получат уведомление, они перейдут к получению данных из буфера события и проанализируют пакет, который был отправлен событием. Как уже упоминалось, выборка и анализ являются чисто логическими вычислениями и очень быстрыми. После этого они могут отправлять запрос (например, отправлять пакет ACK) на нижние уровни. Запросы сверху вниз не блокируют, тоже очень быстрые. Низкие уровни будут обрабатывать запросы и выполнять операции «реальной отправки», иначе говоря, операций ввода-вывода. Верхние и нижние уровни используют средства очереди и т. Д. Для установления связи.

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

Вверх или вниз, это зависит от выбранной вами модели.

См. Также высококонкурентную модель, описанную в ducoment "EffoNetMsg.pdf" на http://code.google.com/p/effonetmsg/downloads/list.

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