metaclass: (Default)
[personal profile] metaclass
Есть такой волшебный паттерн - RAII, и его всякие модификации в языках без автоматического вызова деструкторов(try-finally, using(чего-нибудь IDisposable)) и т.д.
В общем, его применение соответствует тому, что мы создаем/открываем ресурс при входе в блок кода и гарантированно закрываем/разрушаем его при выходе из блока. Причем при любом выходе(в дельфях, например break, continue, exit, выкидывание исключения - все вызывают finally). Но в итоге можно считать, что вход и выход производятся таки вокруг линейного потока выполнения.

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

Вот сижу, думаю, как и чем бы это кошерно описать на c#. Пока ничего толкового в голову не пришло, кроме описания состояний как объектов с полями для каждого нужного ресурса, помеченных специально назначенным атрибутом.
Переход между состояниями это будет хитрая функция, преобразующая объект текущего состояния в объект нового состояния(хотя на самом деле тут есть зло в том, что на самом деле удобнее было бы состояние представить как mix-in из нескольких объектов, и функцию перехода разбить на несколько более простых), перед ее применением будет проверяться не нужно ли разрушить ресурсы из старого состояния, а после применения - не нужно ли создать ресурсов для нового. В большинстве случаев, переход по своей сути и представляет уничтожение старых ресурсов и создание новых, с их инициализацией. Т.е. в функции перехода ничего писать, в общем-то, кроме инициализации ресурсов и не нужно будет - остальное будет выполнено автоматически.

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


Кстати, еще во всем этом меня сильно напрягает идея класса, у которого всегда существует не более одного объекта-экземпляра. Чем-то это противоречит смыслу ООП, по моему.

PS: Кстати, в последнее время все идеи "чего не хватает в языках программирования" сводятся к тому, что линейная одномерная структура текста-кода не всегда адекватно соответствует задаче. Например в ней описывать реляционные таблицы - напряжно, в отличие от их естественного вида-гридов. Про графы вообще речи нет, их удобный для восприятия вид - картинка - дико не удобен для редактирования. Что-нибудь еще более сложное из структур, сложнее графов, бывает?:)

Date: 2009-08-30 07:08 pm (UTC)
From: [identity profile] mend0za.livejournal.com
Напомнил старые добрые дни и язык Ruby.

Там есть именно блоки, для циклов, лямбдей и прочей мишуры.

Зачем дублировать работу Garbage Collector'а ? Нет больше ссылок на объект - в сад.

Date: 2009-08-30 07:18 pm (UTC)
From: [identity profile] vp.livejournal.com
Тут речь о том, что не все так просто. Недостаточно просто когда-нибудь вспомнить, что ага, раз ссылок нет - грохнем объект. Это только для чрезмерно простых случаев, которые по пальцам можно пересчитать. За объектом может стоять ограниченный ресурс, который необходимо вызволить, и самый ключевой момент - именно в контексте заданного рабочего workflow, с контролем, на каком этапе мы находимся, и т.п.

Date: 2009-08-30 07:18 pm (UTC)
From: [identity profile] metaclass.livejournal.com
Ресурс "внешний". Файл в 100 мег размером скачанный с сервера при входе и который обязательно грохнуть при выходе. Ручка к бинарному потоку на железяку, которую нужно открывать и закрывать.

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

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

Date: 2009-08-30 07:27 pm (UTC)
From: [identity profile] mend0za.livejournal.com
В голову приходит только использование деструкторов и явная пристрелка сущностей по истечении времени жизни + reflection чтобы доступаться до него из других ветвей выполнения.

Была в чём-то пересекающаяся задача - по прилёту сигнала (SIGHUP) - зачистить кэши и переоткрыть все файлы. В итоге даже не стали возиться с глобальной регистрацией всего и вся, находили все объекты типа кэш с помощью Object#kind_of? и дёргали найденное за сиську с табличкой flush().
Сами кэши хранились как переменные класса и разделялись соотвественно всеми объектами класса.

Date: 2009-08-30 07:38 pm (UTC)
From: [identity profile] metaclass.livejournal.com
Да, примерно так оно и у меня выходит.
Перебрать поля рефлекшеном, выбрать отмеченные атрибутом "ресурс", грохнуть ненужные, создать новые, инициализировать их.

спасибо)

Date: 2009-08-30 07:12 pm (UTC)
From: [identity profile] krivedkina.livejournal.com
я почти кончаю от большого количества умных слов и умных фраз..:)
извините.

Re: спасибо)

Date: 2009-08-30 07:19 pm (UTC)
From: [identity profile] metaclass.livejournal.com
you are welcome :)

Date: 2009-08-30 09:10 pm (UTC)
From: [identity profile] familom.livejournal.com
Есть такая структура (: Гиперграфами зовется.

Date: 2009-08-30 09:11 pm (UTC)
From: [identity profile] swizard.livejournal.com
> А мне нужно такое же, но для ситуации, когда ресурс живет внутри сложного workflow с ожиданием действий от пользователя.

Примерно с таким я сталкивался в CL, решение получилось что-то из серии (with-resource (resource) (with-call/cc ...))

Без call/cc я честно говоря хз чем эмулировать развесистый workflow в линейном виде. Я не вижу как тут можно подсунуть raii, видимо, надо какое-то другое решение искать.

Date: 2009-08-30 10:04 pm (UTC)
From: [identity profile] thesz.livejournal.com
На ФЯ пробовал? С алгебраическими типами.

Далее это можно один-в-один перенести в C#.

Date: 2009-08-30 10:30 pm (UTC)
From: [identity profile] arush-damage.livejournal.com
имхо тут не на состояния надо ориентироваться а на события.
т.е. объект подписывается на события которые его интересуют и при наступлении определенного события выполняет необходимые действия.
емнип на с# это через делегаты реализуется обычно.

Date: 2009-08-31 12:30 am (UTC)
From: [identity profile] lionet.livejournal.com
В Erlang ты можешь трекать состояние ресурса в процессе, связанном ссылками с другими процессами, которые делают интерактивность какую-то с пользователем. Интерактивность заканчиваеться — твой следитель прибивает ресурс, так как иерархия зависимых подпроцессов сократилась до нуля.

Date: 2009-08-31 02:08 am (UTC)
From: [identity profile] dmzlj.livejournal.com
по моему, графы в виде .dot вполне удобно редактировать. для реляционных таблиц тоже можно что-то придумать (например, SQL?)

Date: 2009-08-31 02:43 am (UTC)
From: [identity profile] zamotivator.livejournal.com
когда состояний штук пять, и в двух из них ресурс не нужен, а в трех нужен, а переходы могут быть какие попало - вручную создавать-разрушать и следить за временем жизни ресурса становится занудно.
В таких ситуациях создаются холдеры - т.е. классы или объекты, или что там ещё, единственная цель которых - захватить ресурс, и освободить его при освобождении холдера.
Таким образом, мы опциональные объекты храним в коллекции холдеров, а коллекции прибиваем гвоздями к объекту, отвечающему за сессию, и который при этом есть всегда - в твоём примере это объект "сессия после логина".

Profile

metaclass: (Default)
metaclass

April 2017

S M T W T F S
      1
2345678
9101112 131415
16171819202122
23242526272829
30      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Aug. 29th, 2025 08:47 am
Powered by Dreamwidth Studios