Комментарии 96
НЛО прилетело и опубликовало эту надпись здесь
Подробнее, пожалуйста.
НЛО прилетело и опубликовало эту надпись здесь
Да вы тут целую статью написали…
> Очень наивная и страшненькая методика построения велосипеда.
«Велосипед» — это еще один метод решения какой-то задачи, для которой уже есть множество вполне удобных решений. Весь смысл статьи как раз в том, что с древнейших времен было изобретено множество велосипедов и ни один из них полностью не обеспечивает должного решения задачи, а чаще всего полученное решение еще и усложняет в Н-цать раз.
Мой «велосипед» ближе всего к тому оригинальному с большущим колесом.
«Велосипед» — это еще один метод решения какой-то задачи, для которой уже есть множество вполне удобных решений. Весь смысл статьи как раз в том, что с древнейших времен было изобретено множество велосипедов и ни один из них полностью не обеспечивает должного решения задачи, а чаще всего полученное решение еще и усложняет в Н-цать раз.
Мой «велосипед» ближе всего к тому оригинальному с большущим колесом.
НЛО прилетело и опубликовало эту надпись здесь
ни один из них полностью не обеспечивает должного решения задачи, а чаще всего полученное решение еще и усложняет в Н-цать раз.На не-функциональных языках функциональное программирование невозможно без самопроизвольного появления разных странных артефактов типа «дизайн-паттернов» и функциональный код с неизбежностью будет выглядеть не особо красиво — хотя бы по сравнению с копи-пастой…
> Мне известен термин «смена состояния».
ОК, давайте еще приведем определение конечного автомата из Теории Алгоритмов и будем тыкать пальцами друг в друга ругаясь на неканоническое его использование. Это какое-то полнейшее занудство.
Да, вероятно, я должен был описать, что смена состояния происходит мгновенно через транзакцию атомарных операций. То есть переход из A в B выглядит так: выполнить код выхода из А, сменить текущее состояние на B, выполнить код входа в B. Но, посчитав это common sense, я данную информацию в статью не включил.
ОК, давайте еще приведем определение конечного автомата из Теории Алгоритмов и будем тыкать пальцами друг в друга ругаясь на неканоническое его использование. Это какое-то полнейшее занудство.
Да, вероятно, я должен был описать, что смена состояния происходит мгновенно через транзакцию атомарных операций. То есть переход из A в B выглядит так: выполнить код выхода из А, сменить текущее состояние на B, выполнить код входа в B. Но, посчитав это common sense, я данную информацию в статью не включил.
Про где что писать, да, возможно не совсем понятно.
В setState пишется уникальная логика выхода из состояния, а в stateBla возможна специфическая логика выхода из состояния A при переходе в Bla. Но очень редко используется.
Как и во всех соглашениях, какой-то код может сперва находиться в одном месте, но потом у него появится другой смысл, или окажется, что он где-то дублируется. Тогда мы можем его перенести в другое место. Никто нам не запрещает. Все-таки код не вытесан из камня, это всего лишь текст, который (о ужас!) можно и нужно менять с развитием проекта.
В setState пишется уникальная логика выхода из состояния, а в stateBla возможна специфическая логика выхода из состояния A при переходе в Bla. Но очень редко используется.
Как и во всех соглашениях, какой-то код может сперва находиться в одном месте, но потом у него появится другой смысл, или окажется, что он где-то дублируется. Тогда мы можем его перенести в другое место. Никто нам не запрещает. Все-таки код не вытесан из камня, это всего лишь текст, который (о ужас!) можно и нужно менять с развитием проекта.
> Машине состояний как конечному автомату совершенно индифферентно предыдущее состояние
В классическом виде да. В классическом виде у состояний не может быть параметров и они не могут хранить данные. Но классические модели и существуют для того, чтобы их модифицировать. Пусть у нас будет FSM с ленточной памятью. Почти машина Тьюринга уже.
Почему люди должны укладывать себя в рамки математического определения конечного автомата? Я в статье его даже не привожу, чтобы народ не пугать.
В классическом виде да. В классическом виде у состояний не может быть параметров и они не могут хранить данные. Но классические модели и существуют для того, чтобы их модифицировать. Пусть у нас будет FSM с ленточной памятью. Почти машина Тьюринга уже.
Почему люди должны укладывать себя в рамки математического определения конечного автомата? Я в статье его даже не привожу, чтобы народ не пугать.
Мда, на первом проекте, по не опытности писал криво. Как итог, решил все вот так, как Вася, «оптимизировать». Уже пол-года вполне рабочий проект пытаюсь переписать с моего убер-фреймворка на простой код.
подобную тему реализовал в своем «форке» бэкбон.js, часто нужно бывает.
правда это не совсем попадает под определение «state machine», но своих плюсов не теряет, да
правда это не совсем попадает под определение «state machine», но своих плюсов не теряет, да
Погуглив пару часов, Вася решает, что State Pattern идеально подходит в данной ситуации.
Вот тут и надо было убивать.
За что и кому? Вася ещё не набил этой шишки, подсказать некому.
За необдуманное применение паттерна.
Это да. Было бы кому. Часто довольно опытные разработчики всё ещё больны переусложнением и пихают паттерны где надо и где не надо «про запас». Новички же у них учатся.
Вот поэтому сначала надо набить по рукам тем, кто переусложняет, а потом заставить их обучить всех заново.
О, это довольно глобальная задача. Набить опытному разработчику гораздо сложнее. Статьи в тему на хабре — неплохой способ.
«Паттерны» надо бы вообще извести как извращение. Вместо них изучать нормальное функциональное программирование.
Да, мы против «паттернов». Мы за функциональное программирование в его чистом, первоначальном виде;-)
Отлично написано!
Единственный вопрос — про судьбу Васи. Не уволили ли его за срыв сроков по сдаче менюшки?
Единственный вопрос — про судьбу Васи. Не уволили ли его за срыв сроков по сдаче менюшки?
После знакомства с реализацией модели акторов в scala периодически возникает желание создать свою истинно верную реализацию конечного автомата на акторах с использованием become, но я пока сопротивляюсь.
использовал в одном проекте компилятор конечных автоматов, придуманный Робертом Мартином и допиленный энтузиастами. Оказался удобной и понятной штукой, причем генерит FSM на нескольких ЯП. Очень упростило разработку…
Кстати, по сути. Ваше соглашение, конечно, выглядит красиво, но у меня вот нет уверенности в том, что все понимают, куда писать код.
А именно: куда писать код для выхода из состояния Idle в состояние Connected (для примера)? В setConnected? Прекрасно, а если у нас тот же код выполняется всегда при выходе из Idle?
Ладно, куда писать, допустим, понятно. А где искать?
В общем, тоже неоднозначно.
А именно: куда писать код для выхода из состояния Idle в состояние Connected (для примера)? В setConnected? Прекрасно, а если у нас тот же код выполняется всегда при выходе из Idle?
Ладно, куда писать, допустим, понятно. А где искать?
В общем, тоже неоднозначно.
«Когда ты только начинаешь пусть, деревья — это деревья, вода — это вода, а горы — это горы. Когда ты пройдешь какой-то отрезок пути, деревья — уже не деревья, вода — не совсем вода, а уж горы — вовсе не горы. И только когда ты придёшь к концу пути, деревья снова окажутся деревьями, вода — водой, а горы — горами.»
Пришел к почти тому же самому (даже перепрыгнув стадии «паттерн» и «хмл»). Плюс к этому подход позволяет всё-таки накидать классов для некоторых состояний, логика обработки которых станет ну очень уж сложной.
Пришел к почти тому же самому (даже перепрыгнув стадии «паттерн» и «хмл»). Плюс к этому подход позволяет всё-таки накидать классов для некоторых состояний, логика обработки которых станет ну очень уж сложной.
Я не понял: если setState() состоит только из state = value, то в какой момент вызывается функция смены состояния типа stateIdle()?
я задам глупый вопрос — а где тут C#? Зачем кодить в стиле Javascript/Java, используя слова-паразиты вроде var, лямбд, неправильную расстановку фигурных скобок и camel именование в примерах, которые по-идее должны быть красивы и удобны для понимания читателя?
Материал безусловно важный, но подача не особенно понравилась. Две из трёх картинок — не в тему.
> Вася заменил кусок императивного кода на кусок декларативного кода, добавив при этом во фреймворк интерпретатор XML, который все еще в пару раз усложнил. А потом попробуй это отдебажить, когда код на разных языках и разбросан по проекту.
Хорошо бы ещё понимать что когда это уйдёт на продакшн, то всё что не конфигурируется, будет периодически возвращаться на доработку программисту, с огромными потерями во времени. Поэтому вынос в XML подобных вещей — шаг правильный, если конечно это можно корректно вынести.
> Вася заменил кусок императивного кода на кусок декларативного кода, добавив при этом во фреймворк интерпретатор XML, который все еще в пару раз усложнил. А потом попробуй это отдебажить, когда код на разных языках и разбросан по проекту.
Хорошо бы ещё понимать что когда это уйдёт на продакшн, то всё что не конфигурируется, будет периодически возвращаться на доработку программисту, с огромными потерями во времени. Поэтому вынос в XML подобных вещей — шаг правильный, если конечно это можно корректно вынести.
Хорошо бы ещё понимать что когда это уйдёт на продакшн, то всё что не конфигурируется, будет периодически возвращаться на доработку программисту, с огромными потерями во времени.
Вечный спор «конфигурируемость vs контролируемость».
Очевидно, решается не по принципу «если можно корректно вынести», а по оценке жизненного цикла одних и других изменений.
Что же у вас за софт такой, где нужно конечный автомат конфигурировать из XML извне?
Понятно, что параметры работы программы хорошо было бы иметь возможность менять без перекомпиляции, но менять принцип работы стейт машины… Это вы уже какой-то интерпретатор непонятно чего написали, который должен уметь делать все.
Понятно, что параметры работы программы хорошо было бы иметь возможность менять без перекомпиляции, но менять принцип работы стейт машины… Это вы уже какой-то интерпретатор непонятно чего написали, который должен уметь делать все.
Поддерживаю. Хрен там вы вынесете логику работы конечного автомата во внешнюю хмл так, чтобы её какой-то админ мог поправить и что-то дельное вышло. Ну разве что в духе «вот сейчас у нас в демке одна логика (пропустим шаг логина, а то задалбывает каждый раз вводить), а потом в продакшене будет чуть другая (логин обязателен)». Но ничего серьёзнее.
Господа теоретики, в нашей организации подобная внешняя конфигурация логики приложения используется, причём давно и в серьёзном софте.
Среди прочих применений — можно изменить логику программы в версии, поставленной на предприятие 10 лет назад, если сейчас уже не осталось ни разработчиков, помнящих тот код, ни окружения, позволяющего *оперативно* развернуть, собрать и протестировать код 10-летней давности (с использованием тогдашних версий библиотек, фреймворков и т.д.).
Среди прочих применений — можно изменить логику программы в версии, поставленной на предприятие 10 лет назад, если сейчас уже не осталось ни разработчиков, помнящих тот код, ни окружения, позволяющего *оперативно* развернуть, собрать и протестировать код 10-летней давности (с использованием тогдашних версий библиотек, фреймворков и т.д.).
Вариант 1 — у нас разное понимание понятия «изменение логики программы» и вариант 2 — у вас хороший архитектор/ведущий разработчик, спроектировавший это. Тогда любите и цените его :)
Сделали просто свой DSL.
Конфигурирование и DSL это разные вещи.
Конфигурирование и DSL это разные вещи.
НЛО прилетело и опубликовало эту надпись здесь
Эдак можно дойти до того что, «вот же консольное приложение, давно-давно написанное, ему на вход передаются файлы и параметры командной строки — и вот какая магия, оно обрабатывает именно эти файлы и именно с этими параметрами!». Понятное дело, если вам нужно по уже известному алгоритму преобразовывать что-то одно в другое, конфигурируя только «что», «куда» и «с какими параметрами», то тут всё ок. А вот возьмите и преобразуйте своей софтиной входящий хмл-документ в картинку формата png, меняя только конфиг.
НЛО прилетело и опубликовало эту надпись здесь
Ну Вы же не будете утверждать, что оно преобразовывает из любого формата в любой?
Ну вообще это возможно — например, если конфиг указывает последовательность вызовов внешних трансформеров. Типичная такая шинка.
НЛО прилетело и опубликовало эту надпись здесь
Ну тут еще надо помнить, что для того чтобы «подправить .sh — скрипт» нужны прямые руки и что-то в голове, а вот откомпиленный сишный модуль можно запустить и он «just works».
Я вообще не противы выноса в конфиги всяких там параметров и констант, но вот когда туда пихают пол-программы, жертвуя удобством написания, отладки, скоростью, безопасностью и надёжностью — это меня смущает.
Я вообще не противы выноса в конфиги всяких там параметров и констант, но вот когда туда пихают пол-программы, жертвуя удобством написания, отладки, скоростью, безопасностью и надёжностью — это меня смущает.
Считаю необходимым отметить, что фактически это выглядит подобно скриптовому языку с рядом особенностей.
Ну то есть программа на программе, причем ответственность за первую переложена на плечи администратора.
Именно за это я и не люблю овер-конфигурабельные системы.
НЛО прилетело и опубликовало эту надпись здесь
Не забываю. Проблема в том, что обычно заказчик в таких случаях если работает, говорит «вот видите, мы сами все можем», а если ломается — то «немедленно почините». При этом конфигурацию из них фиг добудешь, вали в продуктив и разбирайся сам.
НЛО прилетело и опубликовало эту надпись здесь
К сожалению, «обычно» это фикс-прайс контракт на поддержку.
И вот сочетание этих всех вещей (ну и еще некоторого количества чисто архитектурных навыков) и заставляет меня не любить конфигурируемые приложения.
И вот сочетание этих всех вещей (ну и еще некоторого количества чисто архитектурных навыков) и заставляет меня не любить конфигурируемые приложения.
В начале 2008 меня обучали работе на дико неудобной CMS. Я думал долго — подо что же она оптимизирована? И понял — под краткость времени обучения верстальщика. Потом её много материл, реверс-ниженерил и скриптовал…
Про что и речь: вы позволяете себе «в серьезном софте» выкатить на предприятие изменение, не имея возможности его протестировать.
Тестирование изменений в бинарном коде и изменений *только* в логике программы — две разные вещи. Уже как-то маялись с поиском багов, когда изменение пары строчек и перекомпиляция (но с другой версией STL) привело к утечками памяти и сопутствующим непредсказуемым глюкам.
Вдаваться в подробности не хочу, но разумеется изменения в логике проходят тестирование на актуальной версии софта до передачи в продакшн.
Вдаваться в подробности не хочу, но разумеется изменения в логике проходят тестирование на актуальной версии софта до передачи в продакшн.
Вдаваться в подробности не хочу, но разумеется изменения в логике проходят тестирование на актуальной версии софта до передачи в продакшн.
Ну то есть сделать актуальный ландшафт для кода десятилетней давности вы можете, а сделать для него же компиляционное окружение — нет?
сделать актуальный ландшафт для кода десятилетней давности вы можете=«законсервировать» сервер приложений с интсалляшкой. Делов-то…
сделать для него же компиляционное окружение — нетКонсервировать заодно и IDE? Идея в общем-то правильная, но пробивается сильно труднее…
=«законсервировать» сервер приложений с интсалляшкой. Делов-то…
Во-первых, это не будет иметь ничего общего с сервером в продуктиве. А во-вторых, это как раз нетривиально — виртуалки в образах (и любые образа систем) тухнут, а других способов я и не знаю даже.
Консервировать заодно и IDE? Идея в общем-то правильная, но пробивается сильно труднее…
IDE-то зачем? Консервировать надо билд-скрипт и билд-систему, это немного.
> А во-вторых, это как раз нетривиально — виртуалки в образах (и любые образа систем) тухнут,
А можно с этого места поподробнее? Кроме шуток, действительно интересует, как может «стухнуть» образ в виртуалке? А то пользую тут себе и даже не знаю, что меня ждет за углом.
А можно с этого места поподробнее? Кроме шуток, действительно интересует, как может «стухнуть» образ в виртуалке? А то пользую тут себе и даже не знаю, что меня ждет за углом.
Кроме шуток, действительно интересует, как может «стухнуть» образ в виртуалке?
История из жизни: берем машину под Windows, вводим ее в домен (потому что такая конфигурация в продуктиве). Делаем снепшот. Работаем-работаем-работаем. Долго работаем. Откатываем на снепшот, чтобы сделать начисто. Результат: машина не видит домен. Причина: у машины есть доменный эккаунт, который (по умолчанию) нужно продлевать каждые тридцать дней. В снепшоте он старше.
В общем, как-то так. В деталях могу ошибаться.
Еще больше поддерживаю, но только я и автологин из конфига поостерегся бы делать. Ведь в демке должны быть доступны большинство (а то и все) возможностей системы. А значит надо логинится кем-то вроде админа. А потом или кто-то что-то забудет отключить, или скучающий пользователь где-то отроет нужные параметры — и разбирайся потом кто дыру в софте оставил.
Ну вообще тот, у кого есть право менять конфиг системы — это или программер, или админ — а уж они и так и так что угодно с системой могут сделать. Вопрос с «забудет отключить» решается билд-сервером, который не забудет.
Вся задача оптимального программирования — это нахождение такого алгоритма решения задачи, который минимизирует матожидание факапа от его выполнения. Учитывая, что человек (пользователь, админ, настройщик билд-сервера, бизнес-заказчик) может ошибиться — неоптимально закладывать в программу [деструктивные] возможности, не соответствующие решаемой бизнес-задаче.
Уж если надо провести автоматизированное тестирование — лучше сделать отдельный тестовый билд, а ещё лучше — написать юнит-тест (код которого точно не попадёт в боевую систему). А нормальное тестирование проводить на стенде с функционалом, идентичным боевому.
Тут можно вспомнить кучу громких багов, тот же Ariane 5, связанные с неадекватными ожиданиями программистов относительно того, как квалифицированно будет использован их рабочий код.
Уж если надо провести автоматизированное тестирование — лучше сделать отдельный тестовый билд, а ещё лучше — написать юнит-тест (код которого точно не попадёт в боевую систему). А нормальное тестирование проводить на стенде с функционалом, идентичным боевому.
Тут можно вспомнить кучу громких багов, тот же Ariane 5, связанные с неадекватными ожиданиями программистов относительно того, как квалифицированно будет использован их рабочий код.
картинка с Васей в кругу друзей — зачет! чуть не задохнулся от смеха (:
А ещё у Васи блокирующая анимация. Гореть ему в аду.
И не нужно брать пример с Mac OS X — там она тоже криво сделана.
И не нужно брать пример с Mac OS X — там она тоже криво сделана.
Я часто использую автоматы, а иногда даже приходится Марковские Цепи. При этом чтобы код оставался красивым и понятным, чтобы удобно было расширять автомат, надо писать свой builder, фактически DSL. Да, XML и json в данном случае — зло.
Да, спасибо, что напомнили, что надо не только писать не только специфичный метод (или реализатор интерфейса)
stateA_switch1()
(а лучше private static Switcher STATE_A_SWITCH_1 = new Switcher(State.A));
, но и setStateB()
и unsetStateA()
(лучше тоже в виде реализаторов интерфейсов, а не через рефлексию, чтоб IDE лучше хэндлила).НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Простые стейт-машины на службе у разработчика