Дык! Решение довольно необычное и интересное, но всё же, имхо, довольно узкоспециализированное. (В Интернет-магазине скорее всего сработает.)
Мы с вами оба понимаем, что на самом деле код, если он хоть раз потребовал ввода пользователя, будет выполнен не один раз. Но благодаря «магии», программист, использующий ваш «фреймворк», об этом задумываться не будет. И самой первой строчкой метода запомнит в свойствах генерируемого объекта текущее время. А затем будет очень долго дебажить, почему начав бизнес-транзакцию в 11:00:00, в отчёте фигурирует время 11:01:17! Или перед вводом пользователя обновит пару полей в БД (допустим, постепенно формируя заказ и по ходу спрашивая пользователя какие-то уточнения). В итоге, можем получить неконсистентные данные. Как раз потому, что программист не задумался о том, как же на самом деле «магия» работает.
А те же конечные автоматы в целом и NServiceBus в частности, хотя и (как где-то выше верно подметили) усложняют первоначальное восприятие кода, но зато отлично защищают от незнания разработчиком общей архитектуры разрабатываемого его командой ПО. В данном случае это намного важнее синтаксического сахара.
Не критикую, а делюсь опытом: очень советую прочитать пост про Domain Events. Там объясняется, как можно сделать то же самое, но без исключений, а на событиях.
У меня такое ощущение, что вы с автором друг друга не поняли. Судя по описанному выше коду, транзакция будет висеть и после ввода пользователя — стартанёт новая. Если где-нибудь вокруг ExceptionHelper'а её явно не закрыть (можно несложно допилить метод и передавать туда делегат, который вызовется если ответа пользователя ещё нет в БД; но тогда у программиста пропадёт иллюзия того, что его код вызывается 1 раз). Так что мне тоже очень интересно узнать, а как тогда предлагается бороться с транзакциями? Из примеров кода догадаться (мне) нереально :(
По-моему вы изобрели конечный автомат, применение которого в подобных системах реализовано в виде классной штуки под названием NServiceBus. Нет? Длинный процесс разбиваем на шаги и либо дожидаемся его завершения, либо ловим событие\сообщение о необходимости вмешательства пользователя и выводим ему соответствующий MessageBox. По результату закидываем ответ пользователя в уже начатый процесс/автомат и он продолжает свою работу.
О! Я помню пару лет назад пытался разобраться, почему Hibernate не пишет в лог-файл Glassfish! Узнал много нового про log4j, commons-logging и slrf4j (я сам не джавист, мог чутка напутать с названиями) :))
Может кто-нибудь в двух словах объяснить, почему Рельсы больше не рулят и не педалят? Я статью честно прочитал, написано прикольно, но разумного зерна так и не увидел. Как были простыми и понятными, так и остались. И стартуют они адекватно быстро. И писать на них приятно. Зачем мне на ноду то перепрыгивать, почему работодателям я вскоре стану не нужен?
Переменную цикла пишут в скобочках, потому что она локальная для этого цикла: дело не в том, одна она или на каждый чих новая, а в области видимости. Вне цикла её не должно быть
Согласен, со стороны кажется что шаг правильный и важный. Как окажется на самом деле — посмотрим.
Просто какое-то время назад я лично пытался запустить проект с использованием NHibernate на Mono — было какое-то странное падение, то ли непонятный баг. Взял исходники Mono, нашёл в коде стандартной библиотеки причину, подправил и отправил багрепорт кому следует. На самом деле оказалось, что баг был в NHibernate — они по незнанию опирались на поведение .NET, не описанное в официальной спеке. Соответственно, Mono в этом случае вело себя по-другому. Боюсь, подобных нюансов там ещё пруд пруди…
Как бы это меркантильно не звучало, но потеря клиентов интернет-магазина ввиду лежащего хостинга — не вина хостера. Факапы бывают абсолютно у всех, это нужно всегда учитывать. И не перекладывать свою ответственность перед клиентами на вышестоящего поставщика услуг
Можно в двух словах смысл контрактов на примерах? С Мейером лично общался, Эйфель щупал, но в среде .NET на реальных задачах — профита не нашёл (но и глубоко не искал). Т.е. с простыми случаями типа коллекций — понятно. Но именно в мире ынтырпрайза, на примерах ынтырпрайза? Когда у меня есть метод начисления заработной платы для сотрудника, где сотрудник и его должность — это параметры метода начисления денег, которое происходит на счёт сотрудника, являющийся его свойством. Что здесь описать в контракте? Убедиться, что баланс счёта сотрудника вырос на размер зп, дёрнув при этом БД и пройдясь по ассоциациям? Если да, то чем это отличается от покрытия этого же кода — тестами?
Кто разрешал исправлять мою аналогию? :)
Возможно, ваша версия аналогии — это реальное положение вещей в коде, который повлёк за собой данную статью.
Моя версия аналогии — это то, что в этой статье отражено. Есть некий абстрактный код, мы не знаем что конкретно он делает с входным параметром. И есть этот параметр — список. В общем случае обобщать параметр с IList до ICollection — нельзя. Ибо мы не знаем, используется ли там метод IndexOf или что-нибудь из этой оперы. Не зна ем. А вы, видимо — знаете. Но в статье это не описали :)
Мы с вами оба понимаем, что на самом деле код, если он хоть раз потребовал ввода пользователя, будет выполнен не один раз. Но благодаря «магии», программист, использующий ваш «фреймворк», об этом задумываться не будет. И самой первой строчкой метода запомнит в свойствах генерируемого объекта текущее время. А затем будет очень долго дебажить, почему начав бизнес-транзакцию в 11:00:00, в отчёте фигурирует время 11:01:17! Или перед вводом пользователя обновит пару полей в БД (допустим, постепенно формируя заказ и по ходу спрашивая пользователя какие-то уточнения). В итоге, можем получить неконсистентные данные. Как раз потому, что программист не задумался о том, как же на самом деле «магия» работает.
А те же конечные автоматы в целом и NServiceBus в частности, хотя и (как где-то выше верно подметили) усложняют первоначальное восприятие кода, но зато отлично защищают от незнания разработчиком общей архитектуры разрабатываемого его командой ПО. В данном случае это намного важнее синтаксического сахара.
Просто какое-то время назад я лично пытался запустить проект с использованием NHibernate на Mono — было какое-то странное падение, то ли непонятный баг. Взял исходники Mono, нашёл в коде стандартной библиотеки причину, подправил и отправил багрепорт кому следует. На самом деле оказалось, что баг был в NHibernate — они по незнанию опирались на поведение .NET, не описанное в официальной спеке. Соответственно, Mono в этом случае вело себя по-другому. Боюсь, подобных нюансов там ещё пруд пруди…
По поводу лаборатории: вспомните книги Вадима Зеланда и перестаньте придавать факту воспроизведения бага важность :)) Тогда он сразу выстрелит!
Возможно, ваша версия аналогии — это реальное положение вещей в коде, который повлёк за собой данную статью.
Моя версия аналогии — это то, что в этой статье отражено. Есть некий абстрактный код, мы не знаем что конкретно он делает с входным параметром. И есть этот параметр — список. В общем случае обобщать параметр с IList до ICollection — нельзя. Ибо мы не знаем, используется ли там метод IndexOf или что-нибудь из этой оперы. Не зна ем. А вы, видимо — знаете. Но в статье это не описали :)