Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Один обработчик для всех элементов коллекции. Возможно ли? / 13 сообщений из 13, страница 1 из 1
10.08.2005, 11:32:12
    #33208085
Worobjoff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Один обработчик для всех элементов коллекции. Возможно ли?
Надо подписаться на события каждого объекта, содержащегося в коллекции.
Есть ли такая возможность в VB6?
или придется объекты держать в массиве?
...
Рейтинг: 0 / 0
10.08.2005, 13:47:11
    #33208234
Worobjoff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Один обработчик для всех элементов коллекции. Возможно ли?
...
Рейтинг: 0 / 0
11.08.2005, 02:48:28
    #33209404
Victosha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Один обработчик для всех элементов коллекции. Возможно ли?
хорошая ссылка и обсуждение интересное.
вот только никакой "проблемы взаимных ссылок" в этой задаче нет и в помине.
на мой взгляд, Rainbow заблуждается (или заблуждался) в определении "роли и смысла медиатора".
...
Рейтинг: 0 / 0
11.08.2005, 09:54:16
    #33209660
Victosha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Один обработчик для всех элементов коллекции. Возможно ли?
Victoshaхорошая ссылка и обсуждение интересное.
вот только никакой "проблемы взаимных ссылок" в этой задаче нет и в помине.
на мой взгляд, Rainbow заблуждается (или заблуждался) в определении "роли и смысла медиатора".
ну совсем неудачное в первой части получилось высказывание. на ночь глядя.
...
Рейтинг: 0 / 0
11.08.2005, 13:56:01
    #33210444
Worobjoff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Один обработчик для всех элементов коллекции. Возможно ли?
Нда...
Если использовать псевдо-деструктор и не забывать всегда его вызывать перед уничтожением объекта - то никакой циклической ссылки не образуется.
Victosha , для чего ж они тогда применяют "Wrapper" ?
...
Рейтинг: 0 / 0
11.08.2005, 14:32:08
    #33210560
Victosha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Один обработчик для всех элементов коллекции. Возможно ли?
WorobjoffНда...
Если использовать псевдо-деструктор и не забывать всегда его вызывать перед уничтожением объекта - то никакой циклической ссылки не образуется.


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

Worobjoff
Victosha , для чего ж они тогда применяют "Wrapper" ?
истинная цель лежит возле достижения "генеричности" и повторного использования получающегося кода.
----------

Вообще же, в данной конкретной теме одна общая специальная запятая есть - поддержка ByRef параметров "процедур-подписчиков". это тема...

А применительно к показанному примеру - еще и специальная специальная запятая имеется - обработка логически одновременно возникающих событий.
(для конструкций типа набора контролов на форме - этой проблемы в первом приближении нет - там события могут приходить только последовательно).
это еще темастее тема.
...
Рейтинг: 0 / 0
11.08.2005, 16:07:56
    #33210905
Worobjoff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Один обработчик для всех элементов коллекции. Возможно ли?
Если объект коллекции должен посылать событие объекту ее содержащему (назовем его контейнером), то появляется "лишний" публичный метод, с помощью которого и передается событие от элемента коллекции объекту содержащему объект-контейнер. Не всегда желательно "показывать" этот метод.
А вот способ, указанный в ссылке позволяет от него избавиться.
Но, похоже, это не главное для чего его применяют.
...
Рейтинг: 0 / 0
11.08.2005, 17:29:31
    #33211253
Victosha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Один обработчик для всех элементов коллекции. Возможно ли?
если контейнер и управляемое им содержимое вынесены в отдельную dll,
то взаимодействие между ними можно скрыть Friend - методами.

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

код по ссылке от Eduardo A. Morcillo представляет вариант максимально общего вида передачи информации о произошедшем на элементе набора событии. Смотрел я его совсем по диагонали. И с первого просмотра не вынес суждения - решена ли там тема byref параметров. Вполне может быть, что да. надо смотреть подробнее.


упор я на byref-параметрах делаю вот почему.
Если кто-то решил передавать в событие параметр byref, то, вероятнее всего, сделал он это не по недоразумению, а потому, что хотел распорядиться возвращенным значением как управляющим для дальнейшего развития/отмены события.
код инициализации событий такого сорта приблизительно таков
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
Event BeforeUpDate(ByRef Cancel as Integr)
Event AfterUpDate()

Sub UpdateMe
  Dim intReject as Integer
  ...
  RaiseEvent BeforeUpdate(intReject)
  if not  intReject then
     UpdateAtciverecordset
     RaiseEvent AfterUpdate()
  else...
  ...
  End If
  
  ...
End Sub
еще раз: byref-параметры способ передачи информации от "слушателя к источнику", позволяющий управлять развитием события.
И "потерять их по дороге" было бы совсем не здорово.
...
Рейтинг: 0 / 0
12.08.2005, 17:01:31
    #33213624
Victosha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Один обработчик для всех элементов коллекции. Возможно ли?
2 Worobjoff
Выбралось время и нашлись слова ответить чуть подробнее на вопрос о «ролях» .
«Расшифровка» длинновата, но, надеюсь, простится…

‘---------------------------------------

Роль «медиатора» заключается в отделении кода, призванного представлять информацию об объекте - текущем активном источнике события от всего прочего кода. Он должен сконцентрировать на себе как интерфейс, так и по возможности универсальный код, предъявляющий возможным потребителям информацию об источнике события и самом событии. Назовем эту роль «экспозитором», хотя и нет такого слова.
Код, связанной с содержательной обработкой полученного события – это уже код другой категории. Неважно, где эта обработка/реакция будет в конце концов осуществляться – в самом контейнере-менеджере коллекции объектов с событиями или где-то еще.
Кажется, что его можно было бы реализовать непосредственно на «менеджере коллекции событий». Но.
Предположим , что в проекте потребуется несколько разнотипных менеджеров. Тогда класс оболочка источника события окажется зависимым от типа своего владельца. И для оболочек для каждого типа объекта-источника событий потребуется по количеству разнотипных менеджеров. Добавляем в проект новый класс менеджер событий – дописываем специально для него сразу классы –оболочки источников событий. Это как-то совсем плохо выглядит. Было бы лучше, если вновь добавляемый класс-менеджер сумел использовать те классы-оболочки, что уже есть в проекте. Для этого необходимо зафиксировать тип «экспозитора» события. Достаточно стандартно это можно было бы осуществить заявлением специального интерфейса и его реализацией непосредственно в каждом из классов-менеджеров с использованием слова Implements.
В этом месте содержится специфическая проблема. Код таких классов- менеджеров окажется жестко связанным с заявленным интерфейсом. И, при любых его изменениях, потребует внесения изменений сразу во все экземпляры классов-менеджеров. Считается, что одним из признаков «хорошести» проекта – написание его в таком стиле, что вносимые в проект изменения носят локальный характер и по максимуму не требуют вслед за добавлением/изменением строки кода в одном классе каскадных изменений в куче прочих.
Здесь возникает точка принятия решения.
Можно взять на себя обязательство зафиксировать используемые интерфейсы, чтобы при необходимости добавления «экспозитору» какого-то заранее неочевидного функционала, когда спустя какое-то время в проект потребовалось добавить новый тип «менеджера коллекции событий», явно сказать, что создать такой новый «менеджер» по правилам проекта (быстро) нельзя, поскольку это потребует внесения одновременных изменений в слишком большое количество классов.
А можно реализовать «экспозитор» явно в качестве самостоятельного класса, которому менеджер и будет делегировать работу по представлению текущего «активного объекта». Он как явный посредник между «менеджером коллекции» и «оболочкой экземпляра» и был назван в обсуждаемом примере «медиатором». Код проекта должен быть организован по возможности так, чтобы вносимые в такой класс изменения осуществлялись либо только в этом классе, либо, по максимуму - в этом классе и еще одном дополнительном модуле, содержащем вспомогательные функции по работе с классом.
(Осмелюсь попробовать сказать, что упомянутое делегирование – это главный способ «развязки» кода классов в VB6. По крайней мере, в контексте вопросов, так или иначе бродящих вокруг термина «наследование».)


Попробуем накидать штрихи к будущему портрету. В конкретных деталях здесь может быть множество вариаций. Так что далее не более чем одна из возможных линий…


Начнем с класса-оболочки источника событий (допустим, clsEventHolder1. Таких классов нам потребуется по количеству типов «классов для наблюдения» ) Решение вопроса о том, должны ли они реализовывать некий стандартный интерфейс определяется стратегиями создания собственно коллекций и их перечисления. Этот вопрос я совсем опущу и оставлю на ваше усмотрение.

В clsEventHolder1 нам потребуется
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
‘это индивидуальная переменная класса именно того типа,
‘события которого собираемся перехватывать
Private WithEvents pEventSource as AppropriateType

‘это ссылка на наш экспозитор-медиатор
Private  pExpositor as clsEventMediator

‘инициализация оболочки 
Sub Init(uInformed as clsEventMediator, pSource as AppropriateType)…
  Set pEventSource=pSource
  Set pExpositor= uInformed
‘---------------------------------------------------------------------------
‘ избежать «жесткой связи» с «медиатором» можно примерно так  (по McKinney)
‘ Dim tmpObj as clsEventMediator
‘Dim lngPtr as Long
‘lngPtr = ObjPtr(uInformed)
‘CopyMemory tmpObj, lngPtr,  4 
‘Set  pExpositor= tmpObj
‘  CopyMemory tmpObj  0 &,  4 
‘целесообразность и полезность – по собственному усмотрению
‘--------------------------------------------------------------------------
…трам-пам-пам – тут, по необходимости, обеспечили допривязку событий от pEventSource
‘ к приватным функциям, «подписывающимся» на события и выполнили прочий стартовый код…
End Sub

‘это экземпляр функции-получателя события
Private Sub  pEventSource_SomeEvent(byVal param1 As Tram, byRef param2 As Pam)
…’тут еще чуть-чуть поговорим…
End Sub

Во вспомогательном модуле заведем функцию.
Код: plaintext
1.
2.
3.
4.
5.
Public Sub ExposeEventInfo( objModerator As clsEventMediator, objEventInfo as clsEventInfo)
  ‘ тут пока не важно какой конкретный код
  ‘например такой
  objModerator.SetIfoAndRaiseSupplementEvents objEventInfo 
End Sub

Использование такой функции внутри «классов-оболочек» в процедурах обработки событий не просто формально повысит «коэффициент повторного использования» кода. А сделает код «классов-оболочек» полностью независимым от любых будущих изменений в clsEventMediator, фиксируя «точки вмешательства» модулем самого clsEventMediator и свежезачатого вспомогательного модуля (при большом количестве разных классов-оболочек и прочих «мест применения» это становится важным фактором в сохранении управляемости проектом.).
Появившийся вдруг clsEventInfo должен не просто вместить и перенести в себе информацию об источнике события, типе самого события и полученных «первичным получателем» события параметрах, но и обеспечить в необходимых случаях упоминавшуюся поддержку ByRef – параметров.

Макет функции – обработчика события в классе-оболочке тогда получает такие очертания.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
 Private Sub  pEventSource_SomeEvent(byVal param1 As Tram, byRef param2 As Pam)
   ‘фиксируем информацию о событии
   ‘код инициализации clsEventInfo в данном случае случаен, важно, что он просто есть в каком-то виде

   Dim pObjInfo as clsEventInfo
   Set pObjInfo = New  clsEventInfo
  With pObjInfo
    .SetCommonInfoInfo Me,”SomeEvent”
    .AddParam  1 ,”param1”,param1
    .AddParam  2 ,”param2”,,param2
  End With
‘---- наконец извещаем об этом наших «менеджеров и их посредников»
  ExposeEventInfo pExpositor, pObjInfo 
  
  ‘если кто-то хотел как-то среагировать и повлиять на дальнейшее поведение, то, по com-соглашениям, это должно быть уже сделано к данному моменту.
‘Просто отдадим результат чужого творчества объекту источнику события. 
   param2 =  pObjInfo.GetParam(“param2”)
End Sub

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


PS
Малость затянуто, уныло и с излишними умствованиями получилось. Но, может быть, для кого-нибудь все-таки окажется полезным…
...
Рейтинг: 0 / 0
12.08.2005, 17:44:12
    #33213720
Victosha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Один обработчик для всех элементов коллекции. Возможно ли?
читать, аднака, неудобно.
наборалось в ворде. наверно лучше в ворд и скопировать, буде у кого читать охота будет...
...
Рейтинг: 0 / 0
13.08.2005, 16:27:25
    #33214234
Worobjoff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Один обработчик для всех элементов коллекции. Возможно ли?
Да.
С первого прочтения трудно понять. Заинтересовал оставшийся за кулисами clsEventInfo.
...
Рейтинг: 0 / 0
13.08.2005, 16:45:52
    #33214248
Worobjoff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Один обработчик для всех элементов коллекции. Возможно ли?
Если можно, пример структуры clsEventInfo
Как я понял, это - один из устоявшихся приемов (или трюков) программирования в VB.
Хотелось бы применить его "стандартно" (по устоявшимся правилам)
...
Рейтинг: 0 / 0
14.08.2005, 03:56:25
    #33214432
Victosha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Один обработчик для всех элементов коллекции. Возможно ли?
WorobjoffЕсли можно, пример структуры clsEventInfo
Как я понял, это - один из устоявшихся приемов (или трюков) программирования в VB.
Хотелось бы применить его "стандартно" (по устоявшимся правилам)

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

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

Про clsEventInfo.
Назначение экземпляров clsEventInfo – переносить информацию о
произошедшем событии из точек «первичного перехвата» в «оболочках
источников событий» к точкам «содержательной обработки» в «универсальных
обработчиках». В этой роли у Rainbow выступал целочисленный параметр.

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

совсем коротко:
clsEventInfo - это информация.
clsEventMediator - тот, кому должна быть доставлена информация
ExposeEventInfo - способ передачи.


Больше я и не знаю – что еще сказать, не повторившись с "длинной речью".
(уже и начал, фактически...)
...
Рейтинг: 0 / 0
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Один обработчик для всех элементов коллекции. Возможно ли? / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]