![]() |
Модераторы: Partizan, gambit Страницы: (15) Все « Первая ... 2 3 [4] 5 6 ... Последняя »
( Перейти к первому непрочитанному сообщению ) |
![]() ![]() ![]() |
|
Allexx |
|
|||
Новичок Профиль Группа: Участник Сообщений: 13 Регистрация: 16.12.2003 Репутация: нет Всего: нет |
|
|||
|
||||
Domestic Cat |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
-------------------- |
|||
|
||||
stab |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1839 Регистрация: 1.1.2003 Репутация: 22 Всего: 48 |
И так, обобщая по обработке событий в .NET и Java.
1. Java. 1.1 Событие. На уровне языка понятие события отсутсвует, его вынесли на прикладной уровень или не внесли оттуда ![]() а. Самостоятельно поддерживать внутренний список всех подписавшихся на событие объектов. b. Реализовать методы для добавления\удаления подписчиков из внутреннего списка подписавшихся. c. Опубликовать соответствующий интерфейс, который должен быть реализован каждым из объектов-подписчиков. Каких-то строгих требований к реализации, судя по всему, нет. 1.2 Обработчик события (подписчик). Объект реализующий соответствующий интерфейс обрабатываемого им события. По логике, для каждого такого объекта нужен отдельный класс для того, что бы обеспечить различное поведение объектов. 1.3 Код. Прошу знатоков Java привести полный код класса публикующего событие и пример работы с ним. 2. .NET (C#) 2.1 Событие. Понятие события введено на уровне языка. Каждый класс\объект, который заявляет о желании опубликовать событие, должен: а. Объявить соответствующий класс-делегат с требуемой сигнатурой. b. Объявить соответствующий член-событие. Этот член-событие, по сути, является объектом-списком (System.MulticastDelegate) объектов-делегатов (System.Delegate), который реализует всю функциональность по поддержанию списка, добавлению\удалению подписчиков и по оповещению о наступлении события. 2.2 Обработчик события (подписчик). Обработчиком события может быть любой метод с подходящей сигнатурой. Для добавления в список подписчиков информация о методе инкапсулируется в объекте класса System.Delegate. 2.3 Код. (C# 2.0) Класс с событием:
Пример работы:
или так:
-------------------- 6, 6, 6 - the number of the beast. |
||||||
|
|||||||
Domestic Cat |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
Несколько замечаний. 1. За все время мне пришлось самому реализовывать такую вещь один единственный раз. И J2SE, и J2EE содержат достаточное количество листенеров на все случаи жизни. В таких случаях все сводится к
что никак не сложнее делегатов. Если говорить о самой системе листенеров (см. пример выше) Недостаток - писать больше, реально - не намного. Недостатки делегатов, имо: 1. Отсутствие соглашения об именовании делегатов и методов. Можно назвать как хочешь, причем даже осмысленное название часто трудно отличить от названия метода/класса/поля. 2. Делегаты скрывают в себе много автогенерированного кода, внутренний механизм их действия труднее понять. 3. Делегаты, помимо введения двух кейвордов, вводят лишнюю сущность в языке - ссылку на метод, которая более нигде не используется. 4. "Извне" трудно понять, что такое делегат - метод или класс. С одной стороны, это класс, объект которого можно создать через new, с другой стороны, вызывается он как метод. 5. Делегат не может иметь больше одного метода. Часто же нужно несколько методов, сгруппированных по к-л признаку. Например, Java интерфейс MouseListener содержит 5 методов, тогда как в C# требуется 5 делегатов (и, следовательно, 5 классов). 6. Java листенеры более гибки, если я реализую такой листенер сам, у меня есть выбор - как хранить листенеры, в каком порядке вызывать методы, реализовать другие, вспомогательные методы. -------------------- |
||||
|
|||||
batigoal |
|
|||
![]() Нелетучий Мыш ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6423 Регистрация: 28.12.2004 Где: Санктъ-Петербургъ Репутация: 1 Всего: 151 |
Вдогонку - если нам нужно, скажем, только два метода из этих пяти, можно воспользоваться классом-адаптером и переопределить только нужные нам методы. Для остальных будет использована пустая реализация. Мелочь, а приятно. -------------------- "Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли) ЖоржЖЖ |
|||
|
||||
mr.DUDA |
|
|||
![]() 3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 110 Всего: 232 |
В общем, всё сводится к "напишу-ка я всё сам". Т.е. по сути дела, листенеры вообще не нужны, ведь можно обойтись и без них. "Лишний" автогенерируемый код, на самом деле, весь лежит в базовом классе Delegate. Если взять и дизассемблировать сборку, содержащую делегат, в его коде будет всего 3 перекрытых типизированных метода базового класса и конструктор. Возможности, предоставляемые делегатами: 1) Имея объект "делегат", можно получить ссылку на объект содержащий метод (свойство Target), reflection-описание метода (Method); 2) Можно перечислить список всех объектов и их методов, подписанных на делегат (GetInvokeList); 3) Можно вызвать метод(ы), подписанные на делегат, асинхронно!!! Примеры - в MSDN. Умеют ли это листенеры? 4) Можно вызывать метод-подписчик с использованием позднего связывания (late-bound) - метод DynamicInvoke; 5) Можно комбинировать делегаты (метод Combine). Наконец, в листенерах приходится пользоваться switch-ем, а это уже напоминает подход WinAPI. -------------------- ![]() |
|||
|
||||
Domestic Cat |
|
||||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
Но ведь то же можно делать и с листенером.
Все классы в Java, поддерживающие слушателей, имеют методы get<...>Listeners()
Это свойство не делегатов, а фича языка. В Java есть асинхронный вызов методов, см http://java.sun.com/j2se/1.5.0/docs/api/ja...FutureTask.html
Вот с этим я не разбирался, можно пример, чтобы знать о чем речь?
Ну, это то же самое что и +=, и то же самое что просто добавление еще одного листенера в Java.
Сильно сказано; во-первых это не такое уж супер частое явление, во-вторых та же Простая Фабрика пользует свич, но это не значит, что паттерн является чисто процедурным и пришел из винапи ![]() -------------------- |
||||||||||||
|
|||||||||||||
mr.DUDA |
|
||||||
![]() 3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 110 Всего: 232 |
Нет, это не то же самое. Комбинирование производится из двух и более делегатов (а не методов), и результирующий делегат будет иметь список подписчиков из всех перечисленный делегатов.
Вот пример:
Добавлено @ 08:51 З.Ы. неужели, кроме делегатов, никаких принципиальных отличий .NET от JAVA нету ? -------------------- ![]() |
||||||
|
|||||||
Domestic Cat |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
Есть конечно, но пока из делегатов выбраться не можем ![]()
Я пропустил там цитату
то есть вопрос был о DynamicInvoke, не об асинхронном вызове.. Но все равно спасибо. -------------------- |
||||||
|
|||||||
mr.DUDA |
|
|||
![]() 3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 110 Всего: 232 |
Здесь всё просто. Так как все делегаты наследуются от базового класса Delegate, можно хранить и передавать объекты Delegate вместо "конкретных" (типизированных) делегатов. Чтобы вызывать методы, подписанные на такой делегат, и используется DynamicInvoke. Другими словами, можно вызвать любой делегат с любым кол-вом и типом аргументов, используя одну и ту же функцию DynamicInvoke. Термин "late binding" здесь означает позднее связывание (конкретные типы объектов неизвестны на этапе компиляции кода). -------------------- ![]() |
|||
|
||||
Domestic Cat |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
Проще говоря, использовать рефлекшн для вызова метода? В Java рефлекшн есть, потому не проблема.
-------------------- |
|||
|
||||
mr.DUDA |
|
|||
![]() 3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 110 Всего: 232 |
Кстати, а в JAVA можно передать в метод переменное количество аргументов ? Без рефлекшн, конечно.
-------------------- ![]() |
|||
|
||||
Domestic Cat |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
Можно:
-------------------- |
|||
|
||||
alir |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 383 Регистрация: 19.3.2005 Репутация: 2 Всего: 4 |
Я смотрю это ты приколист! .NET вначале проектировался как работающий на любой os, а не только под win. Пока еще есть под freeBSD - и это только начало. И что на счет os? .NET также построен на независимых средствах VM - так что встроить .net в мобилы в будущем тоже реально!
Но ведь раньше и этого не было - примерно год назад (я имею ввиду Россию) вообще за 5 мб не переходило. А сейчас в 16 раз больше + еще карты!
Ты не бойся - как-нить разберутся. p.s. Хотя еще раз повторюсь: скорее всего скоро мобилы уйдут - они полностью перейдут смартофоны. Вот там то .net возьмет свое. |
||||||
|
|||||||
stab |
|
||||||||||||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1839 Регистрация: 1.1.2003 Репутация: 22 Всего: 48 |
Соглашение есть: Класс-делегат: XxxEventHandler Событие: Xxx Обработчик: ИмяОбъекта_Xxx Удобно то, что вся работа с событием сгруппирована минимум в одном члене, в Java же требуется минимум 1 приватный член плюс 2 публичных.
Это называется инкапсуляция. Сомневаюсь, что Java-разработчики имеют исходный код всех классов с которыми работают, вроде на понимании это не сильно сказалось, правда? ;)
А где она (сущность) еще должна использоваться? Понятие "ссылки на метод" присутствует практически во всех современных языках, кроме Java, уж в C++ и Delphi точно есть.
Можно работать полностью как с объектом, если это требуется. Напоминает спор о свойствах, многие сишники говорят, что это тоже лишний элемент. Им не нравится то, что обращение к свойству не возможно отличить от обращения к полю. Им по душе использовать пару методов getXxx, setXxx, а в это время все языки обзавелись свойствами ![]()
Но в тоже время, на каждый обработчик в Java требуется отдельный класс. И еще, представим такую картину: нам нужно обработать только событие MouseDown, в C# назначем обработчик и все. В Java нужно реализовать все пять методов, т.к. требуется реализовать интерфейс, получаем четыри совершенно ненужных и пустых метода.
Имеется возможность ручками обрабатывать добавление\удаление обработчиков:
и ручками вызывать обработчики в каком угодно порядке:
-------------------- 6, 6, 6 - the number of the beast. |
||||||||||||||||
|
|||||||||||||||||
batigoal |
|
||||||
![]() Нелетучий Мыш ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6423 Регистрация: 28.12.2004 Где: Санктъ-Петербургъ Репутация: 1 Всего: 151 |
Отнюдь. Зачем же? Один объект может слушать неограниченное количество событий одинакового или разного типа.
Я уже упоминал - для этого предназначены классы-адаптеры. Давайте уже выйдем, наконец, за пределы обработки событий. Я не знаком с .NET, мне интересно, какие еще есть различия. ![]() -------------------- "Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли) ЖоржЖЖ |
||||||
|
|||||||
![]() ![]() ![]() |
Прежде чем создать тему, посмотрите сюда: | |
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |