Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > Smalltalk
Перезагрузить страницу Как узнать об изменении коллекции в Squeak
Ответ
 
Опции темы Опции просмотра
  (#1 (permalink)) Старый
Андрей А Андрей А вне форума
Новичок
 
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 21.07.2009
По умолчанию 21.07.2009, 18:57

Здравствуйте! Я новичок в SmallTalk и у меня вопрос. Подскажите пожалуйста, как узнать что коллекция изменилась? Например, полем моего объекта является коллекция и я хочу, чтобы объект-владелец был уведомлен, когда в коллекцию что-то добавят извне. Я думал, что это должно работать через механизм зависимостей(addDependent, update и т.д.). Но коллекции в Squeak при изменении свои зависимые объекты не уведомляют. Как быть?
Ответить с цитированием
  (#2 (permalink)) Старый
chaetal chaetal вне форума
Member
 
Сообщений: 42
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 11.04.2005
По умолчанию 22.07.2009, 11:01

Я бы сделал метод добавления в объекте, содержащем коллекцию, и добавлял через него:

MyClass >> addSomething: anObject
collection add: anObject.
self doAnythingOnAdditionOf: anObject.
Ответить с цитированием
  (#3 (permalink)) Старый
Андрей А Андрей А вне форума
Новичок
 
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 21.07.2009
По умолчанию 22.07.2009, 14:52

Спасибо за ответ. Идея с собственным методом добавления мне тоже в голову приходила. Дело в том, что я хочу узнавать не только о добавлении нового элемента в коллекцию, но и вообще о любом изменении коллекции. Если идти путем, который Вы предлагаете, то нужно будет сделать аналогичные методы для удаления элемента, замены и т.д. Это не удобно. Я думал, что могу предоставить клиентам доступ к коллекции и просто получать информацию об изменении. Т.е использовать паттерн "Observer". Очень удивился, когда выяснил что коллекции его не реализуют. Может я что-то не понял? Ведь протокол для работы с dependent-объектами объявлен еще в классе Object.
Ответить с цитированием
  (#4 (permalink)) Старый
chaetal chaetal вне форума
Member
 
Сообщений: 42
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 11.04.2005
По умолчанию 22.07.2009, 16:22

Коллекции (как и большинство "обычных" классов) оповещений не генерируют --- это не их ответственность.

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

Кроме того, длинные "хвосты" --- это запах. То есть я бы предпочел именно

Код:
  myObject add: something.
  myObject remove: somethingElse.
а не

Код:
 
  myObject collection add: something.
  myObject collection remove: somethingElse.

Но если уж решите реализовывать Observer в своей коллекции (IMHO, лучше обертку cделать, чем наследоваться), то рекомендую обратить внимание на Announcements --- "объектная" замена классическим событиям. В Squeak-е было как минимум две их реализации (надеюсь, за прошедшее время они срослись в одну).

А вообще, рекомендую по этим вопросам обращаться непосредственно на мейл-лист Squeak-а (выберите подходящий на http://wiki.squeak.org/squeak/608 --- это, наверное, будет squeak-dev или Squeak Beginners).

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

Цитата:
Спасибо за ответ. Идея с собственным методом добавления мне тоже в голову приходила. Дело в том, что я хочу узнавать не только о добавлении нового элемента в коллекцию, но и вообще о любом изменении коллекции. Если идти путем, который Вы предлагаете, то нужно будет сделать аналогичные методы для удаления элемента, замены и т.д. Это не удобно. Я думал, что могу предоставить клиентам доступ к коллекции и просто получать информацию об изменении. Т.е использовать паттерн "Observer". Очень удивился, когда выяснил что коллекции его не реализуют. Может я что-то не понял? Ведь протокол для работы с dependent-объектами объявлен еще в классе Object.
Ответить с цитированием
  (#5 (permalink)) Старый
chaetal chaetal вне форума
Member
 
Сообщений: 42
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 11.04.2005
По умолчанию 22.07.2009, 17:16

Еще малюсенькое замечание: "Smalltalk" пишется одним словом (не "SmallTalk")
Ответить с цитированием
Ads.
  (#6 (permalink)) Старый
Андрей А Андрей А вне форума
Новичок
 
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 21.07.2009
По умолчанию 22.07.2009, 17:35

Рад завязавшейся беседе. Хорошо, когда есть с кем поговорить о Smalltalk по-русски.

Цитата:
Коллекции (как и большинство "обычных" классов) оповещений не генерируют --- это не их ответственность.
Почему? Как я уже писал, соответствующий протокол объявлен еще в Object. Можно сравнить коллекцию SmallTalk'а и, например TDataset из Delphi. Оба хранят данные, но TDataset может информировать подписчиков о своих изменениях. И это кажется вполне естественным. Более того, было бы очень неудобно писать оберточные методы для TDataset.Append, TDataset.Delete только для того, чтобы в них произвести какие-то дополнительные действия. Гораздо удобнее просто написать обработчик события.

Цитата:
Вообще, ничего страшного в нескольких "оберточных" методах, на мой взгляд, нет.
Позвольте я опишу Вам свою задачу.
Есть объект note, который содержит в себе коллекцию tags. Если я буду делать оберточные методы для добавления, удаления, замещения тегов в заметке, то по логике вещей мне придется "обертывать" еще и такие методы как "collect", "select" и т.д. Если их не обернуть, то значит нужно предоставить доступ клиентам к самой коллекции tags. А это позволит им добавлять и удалять теги без нотификации. Если их оборачивать, то нужно будет написать много лишнего кода, для решения очень простой задачи.
Насколько я понимаю MVC - это одина из основ Smalltalk и почему коллекция не может выполнять функции модели, для меня загадка.
Ответить с цитированием
  (#7 (permalink)) Старый
chaetal chaetal вне форума
Member
 
Сообщений: 42
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 11.04.2005
По умолчанию 22.07.2009, 18:20

Цитата:
Почему? Как я уже писал, соответствующий протокол объявлен еще в Object. Можно сравнить коллекцию SmallTalk'а и, например TDataset из Delphi. Оба хранят данные, но TDataset может информировать подписчиков о своих изменениях. И это кажется вполне естественным. Более того, было бы очень неудобно писать оберточные методы для TDataset.Append, TDataset.Delete только для того, чтобы в них произвести какие-то дополнительные действия. Гораздо удобнее просто написать обработчик события.
Протокол объявлен для того, чтобы любой объект мог рассылать события. Но далеко не каждый объект должен это делать.

С архитектурной точки зрения сравнивать "стандартные" коллекции и TDataset --- не совсем корректно. TDataset, если не ошибаюсь --- давно на Delphi с базами не работал, представляет объекты уровня "бизнес-логики". (Хотя, надо сказать, в Delphi все это страшнейшим образом перемешано...) Коллекции же лежат ниже уровнем --- это модель. И если для бизнес-объектов, действительно, весьма характерно оповещать всех желающих о своих изменениях, модель этого делать не обязана. Именно поэтому, скажем, в VisualWorks придумано несколько ValueModels, которые как раз отвечают за максимально просто обеспечение оповещения об изменениях своих моделей. Как это все решено в Squeak-е я не в курсе.

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

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

Цитата:
Позвольте я опишу Вам свою задачу.
Есть объект note, который содержит в себе коллекцию tags. Если я буду делать оберточные методы для добавления, удаления, замещения тегов в заметке, то по логике вещей мне придется "обертывать" еще и такие методы как "collect", "select" и т.д. Если их не обернуть, то значит нужно предоставить доступ клиентам к самой коллекции tags. А это позволит им добавлять и удалять теги без нотификации. Если их оборачивать, то нужно будет написать много лишнего кода, для решения очень простой задачи.
Насколько я понимаю MVC - это один из стопов Smalltalk и почему коллекция не может выполнять функции модели, для меня загадка.
Все методы collect, select и т.д. возвращают новые коллекции. Так что, без Вашего желания, никто до этой коллекции не доберется

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

Что касается конкретного примера, то мне кажется вполне естественным иметь методы для пометки тэгами note-ов и всего с ними связанного. Попробуйте мыслить со стороны пользователя заметок: ему же не интересно, как там эти тэги хранятся, обрабатываются. Ему нужно знать, какими тэгами она помечена, иметь возможность убрать ненужные тэги, добавить нужные и т.д. Так что можно смело добавлять методы типа #addTag:, #removeTag:, #isTaggedWith: и т.д.
Ответить с цитированием
  (#8 (permalink)) Старый
Андрей А Андрей А вне форума
Новичок
 
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 21.07.2009
По умолчанию 22.07.2009, 19:09

Цитата:
С архитектурной точки зрения сравнивать "стандартные" коллекции и TDataset --- не совсем корректно. TDataset, если не ошибаюсь --- давно на Delphi с базами не работал, представляет объекты уровня "бизнес-логики". (Хотя, надо сказать, в Delphi все это страшнейшим образом перемешано...) Коллекции же лежат ниже уровнем --- это модель. И если для бизнес-объектов, действительно, весьма характерно оповещать всех желающих о своих изменениях, модель этого делать не обязана. Именно поэтому, скажем, в VisualWorks придумано несколько ValueModels, которые как раз отвечают за максимально просто обеспечение оповещения об изменениях своих моделей. Как это все решено в Squeak-е я не в курсе.
Хм. Я плохо разбираюсь в Smalltalk'е. Но разве та модель, к которой относятся коллекции, это не та же модель, которая в MVC?

Цитата:
Кстати, можно еще вспомнить "железный" аргумент всех "C-шников" --- производительность. Оповещение --- весьма и весьма затратная операция (нужно пробежать по всем подписчикам, каждому послать сообщение, дождаться окончания его обработки). А коллекции используются везде, в том числе "в самом сердце" системы и потому должны работать очень быстро.
Я думаю, что если от коллекции требуется производительность, то ведь можно к ней наблюдателей и не добавлять.

Цитата:
В чем такое уж большое неудобство оберточных методов в данном случае, я не вижу. Есть всякие способы их избежать (и в Smalltalk-е их, наверное больше, чем во многих других языках), но эти способы часто будут скрывать смысл происходящего, затрудняя понимание программы со всеми вытекающими...
Для меня неудобство в том, что придется писать методы из двух строчек, ни несущих никакого функционала, кроме отделения клиента от коллекции.
Согласен, способы избежать есть. И спасибо вам за ссылки. Просто в моем представлении Smalltalk был множеством живых и взаимодействующих объектов. Получается, что очень важные объекты не способны взаимодействовать с другими. Не могут общаться полноценно, а только получать сообщения.

Цитата:
Все методы collect, select и т.д. возвращают новые коллекции. Так что, без Вашего желания, никто до этой коллекции не доберется
Я не много о другом. Задача была в том, чтобы получать уведомления при изменении коллекции. Как я уже писал, если не обернуть методы collect и т.д., то нужно дать доступ клиентам к самой коллекции. А это чревато изменением без нотификации.

Цитата:
А если и доберется --- это его проблемы. Мне кажется, в Smalltalk-е вообще несколько отличная от "обычной" философия разработки. Вместо принципа "держать и не пущать" (исходным пунктом которого является предположение о том, что разработчик-пользователь поставляемой системы является идиотом, и его надо максимально ограничивать), практикуется принцип "делай что хочешь (на свой страх и риск)". В общем-то из этого вытекает масса отличительных черт... за которые многие Smalltalk и любят.
Ну я не делаю предположение о том, что пользователь идиот. Я просто уверен в том, что клиенты будут использовать максимально простой для них способ работы с коллекцией тегов. Если они увидят свойство tags, они попытаются сделать add: когда понадобится. И им придется объяснять что нужно пользоваться note addTag:, т.к. tags только для collect, select и т.д.

Цитата:
Что касается конкретного примера, то мне кажется вполне естественным иметь методы для пометки тэгами note-ов и всего с ними связанного. Попробуйте мыслить со стороны пользователя заметок: ему же не интересно, как там эти тэги хранятся, обрабатываются. Ему нужно знать, какими тэгами она помечена, иметь возможность убрать ненужные тэги, добавить нужные и т.д. Так что можно смело добавлять методы типа #addTag:, #removeTag:, #isTaggedWith: и т.д.
Не знаю, что со стороны пользователя удобнее: изучать интерфейс note для работы с тегами или просто работать tags как с коллекцией. Но если учесть, что интерфейс коллекции известен всем, мне второй вариант кажется предпочтительнее.

В любом случае, большое спасибо за Ваше мнение. Очень интересно пообщаться с разработчиком на Smalltalk.
Ответить с цитированием
  (#9 (permalink)) Старый
HandleX HandleX вне форума
Member
 
Сообщений: 40
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 03.04.2007
По умолчанию 22.07.2009, 19:29

Обычно задача оповещать об изменениях в коллекциях часто нужна в гуях.
Списки объектов на экране, да -)
Всё остальное решается другими средствами.
Не знаю как в Squeak, в Dolphin Smalltalk меня очень устраивает класс ListModel для этих целей.

ListModel implements the <listModel> protocol for identity based <sequencedCollecion>s. All of the manipulations that modify the list will trigger notification events such that Observers will be informed of the changes. The <listModel> protocol defines the following events:

#listChanged
#item:addedAtIndex:
#itemRemovedAtIndex:
#itemUpdatedAtIndex:

И т.д. В Squeak нету ничего подобного?
Ответить с цитированием
  (#10 (permalink)) Старый
Андрей А Андрей А вне форума
Новичок
 
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 21.07.2009
По умолчанию 22.07.2009, 21:23

Цитата:
Не знаю как в Squeak, в Dolphin Smalltalk меня очень устраивает класс ListModel для этих целей.

ListModel implements the <listModel> protocol for identity based <sequencedCollecion>s. All of the manipulations that modify the list will trigger notification events such that Observers will be informed of the changes. The <listModel> protocol defines the following events:

#listChanged
#item:addedAtIndex:
#itemRemovedAtIndex:
#itemUpdatedAtIndex:

И т.д. В Squeak нету ничего подобного?
Уверен, что Squeak есть подобные средства. Возможно Announcements это вариант того, о чем Вы говорите.
Просто такая "молчаливость" коллекций не укладывается в мое представление о программе, как о совокупности "живых" объектов. Я думал вся соль Smalltalk в этом.
Ответить с цитированием
  (#11 (permalink)) Старый
chaetal chaetal вне форума
Member
 
Сообщений: 42
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 11.04.2005
По умолчанию 22.07.2009, 22:00

Цитата:
Уверен, что Squeak есть подобные средства. Возможно Announcements это вариант того, о чем Вы говорите.
Просто такая "молчаливость" коллекций не укладывается в мое представление о программе, как о совокупности "живых" объектов. Я думал вся соль Smalltalk в этом.
Announcements --- про другое (я уже, собственно, писал: это аналог Trigger-Event механизма, но события --- как раз живые объекты).
Суть Smalltalk, действительно, по большей части, определяется живыми объектами. Но живость заключается не в том, чтобы каждый объект умел делать все на свете...

В Dolphin-е, если я правильно помню, ListModel как раз в основном используется для построения интерфейсов в рамках MVP. Реализовать аналогичный класс в любом другом Smalltalk-е, естествено, никаких проблем не составляет. Но ни в Squeak-е, ни в VisualWorks среди стандартных коллекций я таких не помню. Почему? Свое мнение я высказал.

Цитата:
Но разве та модель, к которой относятся коллекции, это не та же модель, которая в MVC?
Зависит от задачи. Сейчас обычно (Domain) Model отделяют от View посредством Application Model. Основная задача последней --- перехватывать изменения объектов Domain Model-и и оповещать об этом кого надо. Как раз для того, чтобы не приходилось обычные объекты "затачивать" под требования UI. У Fowler-а (http://martinfowler.com/eaaDev/uiArchs.html) все это неплохо расписано. Где-то был перевод этой статьи на русский.

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

К остальному добавить мне почти нечего... Кстати, могу ошибаться, но, вроде бы, этот вопрос обсуждался в Бековской Smalltalk Best Practice Patterns... В любом случае эта книжка будет очень полезна --- советую.
Ответить с цитированием
  (#12 (permalink)) Старый
chaetal chaetal вне форума
Member
 
Сообщений: 42
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 11.04.2005
По умолчанию 22.07.2009, 22:12

Цитата:
...
вроде бы, этот вопрос обсуждался в Бековской Smalltalk Best Practice Patterns... В любом случае эта книжка будет очень полезна --- советую.
Да. Глава называется Collection Accessor Method. Скачать можно отсюда.
Ответить с цитированием
Ads
  (#13 (permalink)) Старый
Андрей А Андрей А вне форума
Новичок
 
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 21.07.2009
По умолчанию 22.07.2009, 22:20

Спасибо. "Smalltalk Best Practice Patterns" как раз начал недавно читать. Приятно было побеседовать. Удачи.
Ответить с цитированием
Ads
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
С#Интерфейсы и параметризованные коллекции Dash21 .NET 0 29.04.2012 00:33
WPF: глючек при изменении ширины DataGrid Aliq .NET 0 14.02.2012 13:49
Не вызывается редактор коллекции zsv Delphi 1 27.11.2011 22:05
Коллекции портов как реализовать sodind Visual C++ 0 18.05.2011 08:50
Масштабирование компонентов при изменении разрешения *Юльчик* C++ Builder 2 30.06.2010 22:37
ICO коллекции Exmap Офтопик 9 11.09.2008 19:20
ОШИБКА: Невозможно изменить SourceTableName для одного из коллекции. Bred Visual Basic 0 17.08.2007 18:04
Как прикрутить COMEnumerator к перечислению коллекции строк HandleX Smalltalk 0 21.05.2007 10:52
Изменение DataGrid при изменении DataSet DataTable Оксана_laz .NET 0 16.06.2006 17:20
Отображение картинки при изменении размера TImage K2 C++ Builder 9 11.10.2005 09:04
Движение кнопки при изменении размера диалога BabyBear Visual C++ 11 03.10.2005 16:16
Поделитесь XP: VisualWorks - DB - коллекции объектов Life_Freedom_Love Smalltalk 2 28.08.2004 18:58



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов