Делегаты - кто они на самом деле?

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

Как будто я даже не понимаю, почему они у нас есть,как они выгодны и т. д.

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

затем мы можем код-это-выход.

(и FYI, мой конкретный интерес заключается в реализации Objective-C / iPhone App Development, но я действительно думаю, что понимание этого концептуально в первую очередь гораздо важнее.)

спасибо заранее!

6 ответов


что они на самом деле?

специалисты


клиент: привет-вы починили мою машину?

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

клиент: я уже ждал 30 минут, и я действительно в спешке!

сотрудник: Мы очень заняты в это время года.

клиент: вы не кажется занят; Вы были на на стойке регистрации все время!

сотрудник: я не механик. Я управляющий. Ты все еще хочешь, чтобы я починил твои тормоза?


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

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


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

во-первых, сначала фактическое определение глагола делегировать (из Оксфордского словаря):

поручать (задание или обязанность) другой человек, обычно тот, кто меньше старше себя : он делегаты рутинные задачи | власть делегированный ему никогда не должен быть злоупотреблявшее.

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

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

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

это означает, что у вас будет другой класс, который будет реагировать на определенное количество методов, которые объект table будет использовать, как если бы он был часть его основного поведения (например, метод делегата для получения имени столбцов, другой для получения определенной строки и т. д.).). Для конкретного примера вы можете посмотреть NSTableViewDelegate ссылка на протокол: это методы NSTableView может вызвать своего делегата, чтобы получить информацию о различных вещах или настроенном поведении. (The tableView: аргумент в основном каждый метод идентифицирует представление таблицы, вызывающее метод. Часто игнорируется столько делегатов представления таблицы классы существуют для поддержки одного представления таблицы.)

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

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

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


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


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

одним из типичных примеров делегирования является решение о том, следует ли закрывать окно или нет. Когда пользователь нажимает кнопку Закрыть, делегат окна получает -windowShouldClose: и он может либо вернуть да, если окно не содержит каких-либо изменений, которые могли бы сохранить, или нет, если вы хотите дать пользователю возможность сохранить документ перед закрытием его окна.

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


в двух словах, делегат является специалистом для определенной задачи.

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

когда приходит заказ на свадебный торт, владелец готовит тесто и основной торт соответственно и представители фактическая выпечка для patissier, который специализируется на изготовлении свадебных тортов для изготовления всех деталей и глазури.

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

теперь замените бегун пекарни на UITableView, то кондитер с id <UITableViewDelegate> и бухгалтера id <UITableViewDataSource> и мы вернулись к разговору код.


вы можете представить делегата в качестве секретаря членов совета директоров. Давайте посмотрим на ответ на телефон и сохранение его повестки дня/встреч.

любой человек (супер класс? ;)) может ответить на объявление телефона запланировать встречу. Но каждый человек, как ты или Я, делает это по-своему. Так что это означает, что у меня есть anwserphonewithmood: (HumanMood *) настроение; функция, которая отличается от вашей.

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

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

в этом случае, очевидно, секретарь является делегатом.

надеюсь, это делает его более ясным для вас.