После статьи 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. И разработчикам с меньшим опытом будет сложно без этой ясности.
Ответы с перспективы Делегирования
С делегатом мы имеем совершенно другую стратегию. Для наглядности посмотрим на изображение:
Ожидания
Стратегия делегирования имеет дело с протоколами. Протоколы, по своей природе, дают нам путь к:
- Расчету на реализацию необходимого / ожидаемого поведения;
- Предугадыванию каким будет поведение того, кто примет этот протокол. Принимая во внимание соглашения о присвоении имен, я, как делегатор (тот, кто делегирует что-то), считаю разумным ожидать, что вызов метода у моего делегата (тот, кому что-то поручили) может привести к тому, что описывает имя этого метода.
Ощущаемый контроль
Получается так, что в качестве делегатора, я могу контролировать последовательность событий, которые должны произойти, выбирая, когда вызвать методы у делегата. Стратегия с использованием NSNotificationCenter может только посылать уведомления в эфир, надеясь, что кто-то на них среагирует. Стратегия, использующая делегирование, имеет делегата, который принимает протокол. Каждый метод находится в моем распоряжении для вызова в любом порядке, какой мне нужен.
Влияние
Влияние на систему в целом по-прежнему значительное. Поскольку связь между делегатором и его делегатом происходит один-на-один, то определяющим фактором того, насколько широко воздействие, является опора на конструкцию системы в целом. Модели проектирования, минимизирующие или устраняющие глобальное состояние, уменьшают это потенциально широкое влияние.
Одним из преимуществ, которым обладает шаблон делегирования - это то, что делегат соответствует протоколу, а протокол с его определенными методами, имеет имена. Однако этого недостаточно и мы можем лишь использовать это как подсказку в том, какое влияние выполнения методов делегата может быть в системе.
Ясность
Имея преимущество работы с разумно названными протоколами и четко изложенными именами методов, стратегия делегирования, на мой взгляд выигрывает в ясности. Я могу посмотреть на экземпляр делегата и сказать: "Когда выполнение логики этого экземпляра доходит до определенного места, то врывается делегат и происходят события x, y, z. Я могу перепрыгнуть реализации делегата и сказать: "х делает это, у делает это, и z делает что-то другое." Другие разработчики с меньшим знанием приложения в целом будет пользоваться этой дополнительной ясностью довольно легко.
В итоге
Вот, мы и проанализировали NSNotificationCenter, бок о бок с шаблоном делегирования, воображая себя в роли каждого экземпляра (уведомитель, слушатель | делегатор, делегат). Оценили каждую стратегию с точки зрения ожиданий, ощущаемого контроля, влияния и ясности, пытаясь пролить свет на то, что это значит для окружающей среды быть "более структурированный" или "менее структурированным". Я надеялся пролить свет на мое собственное утверждение термина более или менее "структурированной среды", а также поделиться своими мыслями о некоторых последствиях использования каждой из этих двух стратегий.
Что дальше?
Дальше, вы можете продолжить изучать наши туториалы по мере их появления, а также, параллельно читать перевод официальной книги по языку программирования Swift. И, для более подробного изучения языка, вы можете пройти наши курсы!
Урок подготовил: Акулов Иван
Источник урока: Источник