События в системе внедрения зависимостей идут в какую сторону?

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

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

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

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

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

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

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

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

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

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

6 ответов

Решение

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

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

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

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

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

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

РЕДАКТИРОВАТЬ

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

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

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

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

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

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

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

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

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

interface IEventHandler {
    void setNextHandler(IEventHandler nextHandler);
    void handleEvent(Event e);
}

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

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

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

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

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

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

Другие вопросы по тегам