Сравнение NSNotificationCenter и шаблона делегирования.

Если вы нашли опечатку в тексте, выделите ее и нажмите CTRL + ENTER.

После статьи NSNotificationCenter меня попросили подробнее остановиться на утверждении, приведенном мною в диалоге, развернувшемся в комментариях. Оно звучало так:

"Если вам нужна более структурированная среда вокруг вашего коммуникации [instance]-to-[instance], то шаблон делегирования..., вероятно, будут лучшим выбором (чем NSNotificationCenter)."

Я стал размышлять... Что я имел в виду, говоря ", если вам нужна более структурированная среда" ... И как это должно выглядеть? Почему делегаты будут лучшим выбором, когда мне нужна такая "структура"?

Структурированная среда? Что это такое?

"Структурированная среда" может звучать немного расплывчато. Вот о чем я думал, когда это писал: В момент написания комментария, я представлял, как должно выглядеть решение, реализованное с NSNotificationCenter, и как должно выглядеть решение, реализованное с делегатом.

Вопросы

Во-первых, я пытался представить себя в роли каждого экземпляра, и при таком «ролевом» подходе задавал себе следующие вопросы:

  • В качестве экземпляра notifier/delegator (уведомителя/делегатора): "Что я ожидаю должно произойти, когда отправляю это уведомление или вызываю этот метод у делегата? Какие подсказки от контекста исполнения проинформируют меня об этом ожидании? "
  • В качестве экземпляра notifier/delegator (уведомителя/делегатора): "Как я должен контролировать последовательность событий, которые происходят в результате отправки этого уведомления или вызова этого метода у делегата?"
  • В качестве экземпляра listener/delegate (слушателя/делегата): "Какое влияние оказывает это действие на данное уведомление или как исполнение этого метода делегата влияет на систему в целом?"

А затем, возвращаясь к вопросу, и, без ролевой составляющей, задаем более понятные вопросы:

  • "Какая стратегия обеспечивает большую ясность и структуру всей среде приложения?"
  • "Какая стратегия поможет другому разработчику, увидевшему код, проследить логику и влияние кода?"

А судить на сколько эта среда "структурированная" мы сможем, исходя из ответов на вопросы ожидания, ощущаемого контроля, влияния и ясности.

Давайте рассмотрим некоторые ответы с точки зрения каждой коммуникационной стратегии, начиная с NSNotificationCenter.

Ответы на вопросы с перспективы NSNotificationCenter

В NSNotificationCenter в качестве коммуникационной стратегии instance-to-instance, мы имеем следующую среду:

Обратите внимание, что Слушатели от 1 до n могут существовать, а могут и не существовать. Рисунок предполагает, что экземпляры Listener 1+ "настроены" на определенный ключ уведомления.

Ожидания

Что именно должно произойти? Что ж, самое разумное, что я (как "экземпляр уведомителя") ожидаю, так это то, что какой-то другой "Listener" где-то настроится на ключ уведомлений, который я "транслирую". Что произойдет после этого для меня остается загадкой. Это слушатель будет решать сделать ли что-то разумное с уведомлением о произошедшем или нет. Я, как уведомитель, ничего большего ожидать не могу.

Ощущаемый контроль

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

Фантастика! Можно легко сказать: "Эй! Это случилось! ", а только затем это происходит. Но я называю это "менее структурированным".

Влияние

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

Ясность

Когда в приложении происходит усиленная эксплуатация NSNotificationCenter, то мы теряем ясность. Для использования в вашем приложении NSNotificationCenter должно подбираться подходящее время. Имейте в виду, что разобраться во взаимодействиях становится намного сложнее, когда все больше и больше экземпляров слушателя отвечают на уведомления. Пытаясь рассуждать о том, как вся система пришла к своему нынешнему состоянию непросто, когда появляется NSNotificationCenter. И разработчикам с меньшим опытом будет сложно без этой ясности.

Ответы с перспективы Делегирования

С делегатом мы имеем совершенно другую стратегию. Для наглядости посмотрим на изображение:

Ожидания

Стратегия делегирования имеет дело с протоколами. Протоколы, по своей природе, дают нам путь к:

  1. Рассчету на реализацию необходимого / ожидаемого поведения;
  2. Предугадыванию каким будет поведение того, кто примет этот протокол. Принимая во внимание соглашения о присвоении имен, я, как делегатор (тот, кто делегирует что-то), считаю разумным ожидать, что вызов метода у моего делегата (тот, кому что-то поручили) может привести к тому, что описывает имя этого метода.

Ощущаемый контроль

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

Влияние

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

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

Ясность

Имея преимущество работы с разумно названными протоколами и четко изложенными именами методов, стратегия делегирования, на мой взгляд выигрывает в ясности. Я могу посмотреть на экземпляр делегата и сказать: "Когда выполнение логики этого экземпляра доходит до определенного места, то врывается делегат и происходят события x, y, z. Я могу перепрыгнуть реализации делегата и сказать: "х делает это, у делает это, и z делает что-то другое." Другие разработчики с меньшим знанием приложения в целом будет пользоваться этой дополнительной ясностью довольно легко.

В итоге

Вот, мы и проанализировали NSNotificationCenter, бок о бок с шаблоном делегирования, воображая себя в роли каждого экземпляра (уведомитель, слушатель | делегатор, делегат). Оценили каждую стратегию с точки зрения ожиданий, ощущаемого контроля, влияния и ясности, пытаясь пролить свет на то, что это значит для окружающей среды быть "более структурированный" или "менее структурированным". Я надеялся пролить свет на мое собственное утверждение термина более или менее "структурированной среды", а также поделиться своими мыслями о некоторых последствиях использования каждой из этих двух стратегий.

Что дальше?

Дальше, вы можете продолжить изучать наши туториалы по мере их появления, а также, параллельно читать перевод официальной книги по языку программирования Swift. И, для более подробного изучения языка, вы можете пройти наши курсы!

Урок подготовил: Акулов Иван

Источник урока: Источник