Модель делегата Obj-c - на Java? - PullRequest
1 голос
/ 16 января 2010

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

В Какао на Mac OS X я бы написал и внедрил модель делегата. А как насчет Java? (Пока что я просто передаю 'this' в качестве аргумента при инициализации нового объекта, чтобы сохранить ссылку на него из нового объекта.)

Ответы [ 2 ]

3 голосов
/ 16 января 2010

В Какао / Objective-C делегаты - это объекты, которые придерживаются указанного протокола. Интерфейс Java аналогичен протоколу Objective C, за исключением того, что Java не разрешает дополнительные методы: если ваш класс реализует интерфейс, вы должны реализовать все методы.

Если вы хорошо владеете всеми необходимыми методами делегата, просто определите интерфейс и используйте его.

Если ваш интерфейс делегата имеет много методов, и было бы удобно сделать некоторые из них необязательными, вы можете определить класс Adapter, который реализует интерфейс делегата, предоставляя реализацию по умолчанию для каждого из методов. Чтобы использовать его, ваш класс делегата должен либо расширить класс адаптера, либо, если это невозможно, определить частный внутренний класс, который расширяет класс адаптера. (Посмотрите на интерфейс Java MouseListener и класс MouseAdapter для примера этого.)

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

0 голосов
/ 16 января 2010

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

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

Как это работает

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

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

Чтобы быть потокобезопасным, массив параметров должен существовать уникально для каждого вызова метода API, и для эффективности тот же самый должен использоваться для каждого вызова обратного вызова; Мне нужен был второй объект, который было бы дешево создать, чтобы связать обратный вызов с массивом параметров для вызова. Но в некоторых случаях вызывающий уже имел массив параметров по другим причинам. По этим двум причинам массив параметров не принадлежит объекту Callback. Кроме того, выбор вызова (передача параметров в виде массива или отдельных объектов) принадлежит API, использующему обратный вызов, позволяющий ему использовать любой вызов, который лучше всего подходит для его внутренней работы.

Тогда вложенный класс WithParms является необязательным и служит двум целям: он содержит массив объектов параметров, необходимый для вызовов обратного вызова, и предоставляет 10 перегруженных методов invoke () (с 1 до 10 параметрами), которые загружают параметр массив, а затем вызвать цель обратного вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...