2009-12-22 2 views
14

Я имею дело с некоторыми асинхронными ситуациями связи (управляемый событиями анализ XML, обработка ответа NSURLConnection и т. Д.). Я попытаюсь кратко объяснить свою проблему:Объективная-асинхронная связь: цель/действие или шаблон делегирования?

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

Я пытаюсь найти своего рода шаблон или правило для реализации такого рода вещей, и я вижу 3 возможных решений:

1. Используйте шаблон делегации: клиент службы провайдера делегат, и он получит результаты после завершения задачи.

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

3. Использовать оповещения.

(Update) Через некоторое время попытки решения # 2 (цель и действия), я пришел к выводу, что, в моем случае, это лучше использовать подход делегирования (# 1). Вот плюсы и минусы каждого варианта, как я их вижу:

Делегирование подход:

  • 1 (+) Достоинством варианта 1 является то, что мы можем проверка компиляцией -time ошибки, потому что клиент должен реализовать протокол делегирования поставщика услуг.

  • 1 (-) Это также недостаток, потому что это заставляет клиента быть тесно связан с поставщиком услуг, поскольку он должен реализовать свой протокол делегатов.

  • 1 (+) Это позволяет программисту легко просматривать код и находить, какой метод клиента, поставщик услуг вызывает для передачи своих результатов.

  • 1 (-) С точки зрения клиента, не так просто найти, какой метод будет вызываться поставщиком услуг после его получения. Это все еще легко, просто перейдите к методам протокола делегата, и все, но подход №2 более прямой.

  • 1 (-) Мы должны написать еще код: определить протокол делегата и реализовать его.

  • 1 (-) Кроме того, шаблон делегирования должен использоваться, действительно, для делегирования поведения. Этот сценарий не будет точным случаем делегирования, семантически.

Действие/Целевой подход

  • 2 (+) Достоинством варианта 2 является то, что при использовании метода поставщика услуг вызывается, то @selector указав действие обратного вызова должен также указывается, поэтому программист точно знает, какой метод будет вызван для обработки результатов.

  • 2 (-) В противовес этому трудно найти, какой метод будет вызываться на клиенте во время просмотра кода поставщика услуг. Программист должен перейти к вызову службы и увидеть, какой @selector передается.

  • 2 (+) Это более динамичное решение и вызывает меньшее сцепление между частями.

  • 2 (-) Возможно, одна из самых важных вещей: Это может привести к ошибкам во время выполнения и побочные эффекты, так как клиент может передать селектор, который не существует для поставщика услуг.

  • 2 (-) Используя простой и стандартный подход (#performSelector: withArgument: withArgument :) поставщик услуг может передавать только до 2-х аргументов.

Уведомления

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

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

Я что-то упустил? что вы рекомендуете и почему?

Спасибо!

ответ

0

Очень хороший вопрос.

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

if([delegate respondsToSelector:callback]){ 
    //call to callback here 
} 

Надежда, что помогает взвесить варианты

+0

Thanks Mihirsm, Вы правы, что предотвратит ошибку во время выполнения. Но тем не менее тот факт, что программист использовал неправильный селектор, не будет отображаться до времени выполнения. Это может создать побочные эффекты: S. Опять же, плюс для более статического, но безопасного механизма делегирования. Приветствия! – Lio

+1

Вы можете сделать это немного безопаснее, выполнив @protocol и совместив делегата с этим протоколом. Это гарантирует, что класс делегата реализует необходимые методы. Вы также можете добавить утверждение в свой метод setDelegate: чтобы проверить соответствие нового объекта протоколу. –

+0

Метод по умолчанию для методов, объявленных в протоколах, для них является '@ optional', поэтому' [delegate отвечаетSoSelector: callback] 'по-прежнему необходимо. Вы можете использовать '@ required' в своем протоколе, но я обнаружил, что большинство людей этого не делают. Моим решением было создать батут 'NSProxy', возвращенный расширением' NSObject', '- [NSObject ifResponds]'. Просто синтаксический сахар, который позволяет вам не иметь все, что «если» ерунда. –

3

Вы скучали третий вариант - уведомления.

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

Это позволяет легко снимать сцепление; некоторые из решений сводятся к тому, хотите ли вы систему push/pull.

+0

Спасибо Ciarán, Я не взвесил Уведомления только потому, что я думаю, что они должны использоваться, когда необходимо уведомлять более одного объекта. Кроме того, я думаю, что в таких ситуациях лучше иметь возможность напрямую разговаривать с клиентом (с точки зрения поставщика услуг), чтобы сообщить, что операция завершена. Но, конечно, уведомления - это еще один способ справиться с этим. Возможно, я обновлю вопрос позже, включая уведомления, но пока я хочу посмотреть, что произойдет. : D Еще раз спасибо! – Lio

0

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

Это заставило меня пойти на подход Action/Target. Мой поставщик услуг имеет состояние и распределяется между несколькими клиентами.