Паттерн "Наблюдатель"

Mols

Новичок
Доброго времени суток)
Возникла у меня задачка навроде обработки событий.
Имеется иерархическая структура. Например:

1. Раздел (например промтовары)
1.1 Категория (например спорт)
1.1.1 Тип товаров (кроссовки)
1.1.1.1 Кроссовки марки Puma
1.1.1.1.1 Модель "Супер"

Допустим для кроссовок "Супер" - меняется цена или добавляется отзыв (в общем производится некое действие).

Как правильно сообщить об этом заинтересованным объектам?
Например надо:
1. установить значение в "время_последних_ изменений" для 1.1.1 Тип товаров (кроссовки) или любого другого (в общем для произвольного "родителя" и для произвольного их числа)
2. разослать письма всем, кто подписался "следить за изменениями цен Модели "Супер""
3. Ещё что угодно

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

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

Пихать в диспетчер... это уже вроде не совсем "Наблюдатель"...

Кто решал подобную задачу (или видит грамотное решение), поделитесь мнением пожалуйста..
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
надо сделать поддержку событий в предке модели
для обновления времени изменения я бы прописал обработчик в самой модели,
в обработчике создавал бы модель родителя, и так каскадно вверх по цепочке

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

на каждое действие свой обработчик, в принципе, несложно
 

Активист

Активист
Команда форума
Жесть. Вы понимаете, что пишете?

А у вас сущевствуют объекты
- Раздел (например промтовары)
- 1.1 Категория (например спорт)
- 1.1.1 Тип товаров (кроссовки)

Если да, то покажите свойства экземляров этих объектов через вардамп, там и посмотрим.

> Как правильно сообщить об этом заинтересованным объектам?
Написать скрипт, который обновит данные в субд! Ваша задача не сводится к ООП вообще, ваша задача сводится к обновлению данных в БД по дереву, ну так просто - поменяйте эти данные. Если же действительно, вы создаете объекты - то применить обсервер не составит труда, кроме того, я сомневаюсь, что вы создаете объекты всего дерева, слишком уж накладно будет для обычного изменения "даты" или еще каких-либо других свойств.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
ну да, Активист прав, я как-то слишком простодушно принял описание проблемы
 

Mols

Новичок
Жесть. Вы понимаете, что пишете?
Конечно понимаю.
А у вас сущевствуют объекты
.......
кроме того, я сомневаюсь, что вы создаете объекты всего дерева, слишком уж накладно будет для обычного изменения "даты" или еще каких-либо других свойств.
Читаем до полного просветления
В моём случае при изменении цены мы имеем доступ только к сущности с данными о 1.1.1.1.1 Модель "Супер". Все кто выше - не создаются, соответственно не подписываются на сообщения.
И будьте поспокойней.
Я не писал, что объекты существуют. я писал "Имеется иерархическая структура."
Проблема именно в том, что на момент редактирования объекта они не создаются.


Ещё раз, учитывая Вашу невнимательность поясняю.
1. Объекты всего дерева я конечно не создаю.
2. Объекты всего дерева вообще нафиг не нужны для решения этой задачи. Нужны только родительские.
3. Родительские объекты не создаются при редактировании дочернего(это вроде черным по белому написано в первом посте). Если быть точнее иногда могут быть созданы при проверке прав, но совсем не обязательно.

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

Активист

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

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Все сопли по поводу "обсуждать реальную задачу" оставляем себе.
Всё что мне интересно - описано в моём примере.
а с другой стороны - ну и обсуждай это с самим собой, идеальный собеседник получится
 

Mols

Новичок
Вообще мне понравился первый пост grigori
Я похоже в "Наблюдатель" хочу запихнуть лишнее.
Надо действительно сделать "всплывающие" события.

А вообще, возмите за основу алгоритмы nested sets (nested tree).
У меня нет проблем работы с деревом.
Вложенности не большие. Достать всё что нужно просто.

У меня проблема с организацией взаимодействия.
То есть где именно и как хранить логику реакции на изменения.

1. в самой модели (будет много знать о других моделях)
2. в контроллере где происходит редактирование (тогда надо в каждом контроллере цеплять например "рассыльщик")
3. в каком-то диспетчере
4.... т.п.

Иерархия это только часть задачи. И как раз её наверное лучше делать не через "Наблюдатель"
 

Mols

Новичок
а с другой стороны - ну и обсуждай это с самим собой, идеальный собеседник получится
Ни в коей мере не хотел никого обидеть.
Просто если люди не вникая в пост начинают говорить мягко говоря "не вежливо" я бы не хотел от таких людей выпендрёжа в стиле "реальные задачи".
Задача в общем абстрактная. Описана на примере который можно "схватить" сходу. По крайней мере я на это надеюсь.
Но конечно нож к горлу никто приставлять не будет.
Не хотите участвовать не надо. Что тут сделаешь?
Хотя Ваше мнение, в принципе, мне всегда интересно.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Mols, в его словах нет ничего невежливого - просто предложение показать код
обижаться на то, что вопрос заставил тебя признать, что вся эта тема - плод твоего воображения ... а мы тут при чем? :)
если задача абстрактная - так и пиши "вот абстрактный объект в вакууме", а не "вот записи о товарах и категориях в базе"
мы же не фантасты, мы инженеры, любим точность
 

Mols

Новичок
grigori
Зачем из пальца?
Не из пальца.
Просто реально описывать что надо делать - замахаешься.
Штук 6-7 видов разных объектов которые могут быть привязаны друг к другу.
Всё это описать во всех вариациях сложно.
Задача простая - убрать проблему отсутствия созданных объектов наблюдателей.
Задача специфичная именно для веба, и я думаю её решение было бы полезно не только мне.
Вот открываем книжку "Приемы объектно ориентированного проектирования". от известных 4х авторов...
Видим паттерн "Наблюдатель" - вроде с виду подходит.
Но описан он на примере десктопного приложения.
Где "наблюдатели" уже созданы априори.
Хочется понять можно ли это экстраполировать на веб или нет.
И если да, то с какими оговорками.

А "вежливый" господин прочитал начальный пост по диагонали.
Увидел то, чего там нет.
И выступил с "глубоким анализом того чего нет". не?

З.Ы.
Всё ж таки я надеюсь, что это просто тяпница виновата.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
ну не из пальца, я исправил
короче, мнение об абстрактных связанных объектах я написал, образец реализации - jQuery, yii
 

Mols

Новичок
grigori
Мде... если я таки плохо/не понятно сформулировал задачу задайте лучше уточняющие вопросы.
Но только не в виде "покажи дамп объектов" об отсутствии которых прямо сказано. Ок?
 

Mols

Новичок
Дык я вроде постарался...
Лан. На лурк не пойду)))
Дерьмо, а не ресурс.
Да и Вам вроде как не по чину таким детством страдать)))
За совет о том, чтобы разделить обработку спасибо.
Как минимум вывел меня из ступора.
 

tz-lom

Продвинутый новичок
честно говоря никогда не понимал целесообразности слот-сигнальных систем в скриптах которые живут 1-2 секунды и посылают пару-тройку сигналов за всё время
 

whirlwind

TDD infected, paranoid
Mols Все правильно ты думаешь. Только делаешь Observable не класс модели, а класс дата-маппера модели. И события соответственно onUpdate с передачей экземпляра класса модели.
 
  • Like
Реакции: Mols

Активист

Активист
Команда форума
Обсуждаем что-то крайне абстрактное, причем здесь обсервер? Нужены реальные данные - струкутура БД, вырезки реального кода.
Давайте хотя бы вашу архитектуру увидим.
 

whirlwind

TDD infected, paranoid
Активист зачем тебе реальные данные?

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

Варианта тут я вижу 2:
1. Менее структурированный: это как я сказал DataMapper extends Observable и подписываться один раз на события нужного датамаппера (ну или репозитория, если это не persistent). Тут сложность в отслеживании корректности связей при внесении изменений. Это специфика паттерна - observable и observer связываются через третий интерфейс, и код не сразу отреагирует на некорректно-внесенные изменения (пока событие не возникнет). Наличие тестов решает эту проблему.
2. Более структурированный: сервисный слой. Примерно
PHP:
class ItemService {
   function updateItem(Item $item) {
       $this->items->save($item);
       // check owner item
       // notify recipients
       // etc
   }
}
Тут тоже мухи от котлет отдельно, но контроллеры должны обращаться к модели не напрямую, а через сервисный слой. А изменить это на этапе рефакторинга можно только вспомнив про все контроллеры, что не всегда просто.
 
Сверху