Pull to refresh

Comments 96

UFO just landed and posted this here
UFO just landed and posted this here
Да вы тут целую статью написали…
UFO just landed and posted this here
> Очень наивная и страшненькая методика построения велосипеда.

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

Мой «велосипед» ближе всего к тому оригинальному с большущим колесом.
UFO just landed and posted this here
В первом более автоматном примере там цикломатическая сложность кода выше и сам код длиннее… менее красиво…
ни один из них полностью не обеспечивает должного решения задачи, а чаще всего полученное решение еще и усложняет в Н-цать раз.
На не-функциональных языках функциональное программирование невозможно без самопроизвольного появления разных странных артефактов типа «дизайн-паттернов» и функциональный код с неизбежностью будет выглядеть не особо красиво — хотя бы по сравнению с копи-пастой…
> Мне известен термин «смена состояния».

ОК, давайте еще приведем определение конечного автомата из Теории Алгоритмов и будем тыкать пальцами друг в друга ругаясь на неканоническое его использование. Это какое-то полнейшее занудство.

Да, вероятно, я должен был описать, что смена состояния происходит мгновенно через транзакцию атомарных операций. То есть переход из A в B выглядит так: выполнить код выхода из А, сменить текущее состояние на B, выполнить код входа в B. Но, посчитав это common sense, я данную информацию в статью не включил.
UFO just landed and posted this here
Про где что писать, да, возможно не совсем понятно.

В setState пишется уникальная логика выхода из состояния, а в stateBla возможна специфическая логика выхода из состояния A при переходе в Bla. Но очень редко используется.

Как и во всех соглашениях, какой-то код может сперва находиться в одном месте, но потом у него появится другой смысл, или окажется, что он где-то дублируется. Тогда мы можем его перенести в другое место. Никто нам не запрещает. Все-таки код не вытесан из камня, это всего лишь текст, который (о ужас!) можно и нужно менять с развитием проекта.
> Машине состояний как конечному автомату совершенно индифферентно предыдущее состояние

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

Почему люди должны укладывать себя в рамки математического определения конечного автомата? Я в статье его даже не привожу, чтобы народ не пугать.
UFO just landed and posted this here
Мда, на первом проекте, по не опытности писал криво. Как итог, решил все вот так, как Вася, «оптимизировать». Уже пол-года вполне рабочий проект пытаюсь переписать с моего убер-фреймворка на простой код.
подобную тему реализовал в своем «форке» бэкбон.js, часто нужно бывает.
правда это не совсем попадает под определение «state machine», но своих плюсов не теряет, да
Погуглив пару часов, Вася решает, что State Pattern идеально подходит в данной ситуации.

Вот тут и надо было убивать.
За что и кому? Вася ещё не набил этой шишки, подсказать некому.
За необдуманное применение паттерна.
Это да. Было бы кому. Часто довольно опытные разработчики всё ещё больны переусложнением и пихают паттерны где надо и где не надо «про запас». Новички же у них учатся.
Вот поэтому сначала надо набить по рукам тем, кто переусложняет, а потом заставить их обучить всех заново.
О, это довольно глобальная задача. Набить опытному разработчику гораздо сложнее. Статьи в тему на хабре — неплохой способ.
Статьи в тему на хабре — неплохой способ.

Вот в этом я, кстати, не уверен.
  1. Часть «опытных разработчиков» не читает Хабр (это по результатам собеседований)
  2. Часть «опытных разработчиков» считает, что знает лучше, чем абстрактный автор статьи на хабре.


Да, я понимаю, что звучит как безнадега.
Мы же с вами тут все разработчики опытные, сами все знаем. Не то что Вася.
Именно. В комментах это хорошо видно.
1. Читают довольно много. Это уже что-то.
2. Это они отписываются, что как-бы всё знают. На самом деле многие обдумывают.
«Паттерны» надо бы вообще извести как извращение. Вместо них изучать нормальное функциональное программирование.
Да, мы против «паттернов». Мы за функциональное программирование в его чистом, первоначальном виде;-)
Утверждаете, что в ФП нет ни одного паттерна? Ну-ну.
Было бы полезно накидать ссылок на существующие «фреймворки». Начать наверно стоит с ragel.
Если бы статья была про фреймворки, то да.
Но статья против фреймворков. Если кому-то действительно он нужен, первая же страница поиска в гугле выдаст множество вариантов.
Отлично написано!

Единственный вопрос — про судьбу Васи. Не уволили ли его за срыв сроков по сдаче менюшки?
Отличная идея! Можно потом невозбранно утроить бюджет на менюшку, чем сильно поднять её важность относительно других заданий.
После знакомства с реализацией модели акторов в scala периодически возникает желание создать свою истинно верную реализацию конечного автомата на акторах с использованием become, но я пока сопротивляюсь.
На универсальность это ни в коем случае не претендует, так как далеко не везде есть удобные акторы и далеко не во всех акторах есть аналог become.

С другой стороны этот подход кажется уж очень естественным.
«Пишем на ассемблере, думая на ЛИСПе»…
Наверное, в Scala и дизайн-паттерны не применяются ибо без них всё яснее?
использовал в одном проекте компилятор конечных автоматов, придуманный Робертом Мартином и допиленный энтузиастами. Оказался удобной и понятной штукой, причем генерит FSM на нескольких ЯП. Очень упростило разработку…
Спасибо за наводку, очень интересная по описанию вещь.
А с Ragel не сравните?
Кстати, по сути. Ваше соглашение, конечно, выглядит красиво, но у меня вот нет уверенности в том, что все понимают, куда писать код.

А именно: куда писать код для выхода из состояния Idle в состояние Connected (для примера)? В setConnected? Прекрасно, а если у нас тот же код выполняется всегда при выходе из Idle?

Ладно, куда писать, допустим, понятно. А где искать?

В общем, тоже неоднозначно.
Ну что же вы остановились на полпути.
Был бы идеальный вопрос. Сам спросил — сам ответил!
«Когда ты только начинаешь пусть, деревья — это деревья, вода — это вода, а горы — это горы. Когда ты пройдешь какой-то отрезок пути, деревья — уже не деревья, вода — не совсем вода, а уж горы — вовсе не горы. И только когда ты придёшь к концу пути, деревья снова окажутся деревьями, вода — водой, а горы — горами.»

Пришел к почти тому же самому (даже перепрыгнув стадии «паттерн» и «хмл»). Плюс к этому подход позволяет всё-таки накидать классов для некоторых состояний, логика обработки которых станет ну очень уж сложной.
Я не понял: если setState() состоит только из state = value, то в какой момент вызывается функция смены состояния типа stateIdle()?
Наоборот, смена состояния идет вызовом метода stateIdle(), который в свою очередь уже вызывает setState.
я задам глупый вопрос — а где тут C#? Зачем кодить в стиле Javascript/Java, используя слова-паразиты вроде var, лямбд, неправильную расстановку фигурных скобок и camel именование в примерах, которые по-идее должны быть красивы и удобны для понимания читателя?
Вообще-то, var и лямбды идиоматичны для C# начиная с третьей версии.
Материал безусловно важный, но подача не особенно понравилась. Две из трёх картинок — не в тему.

> Вася заменил кусок императивного кода на кусок декларативного кода, добавив при этом во фреймворк интерпретатор XML, который все еще в пару раз усложнил. А потом попробуй это отдебажить, когда код на разных языках и разбросан по проекту.

Хорошо бы ещё понимать что когда это уйдёт на продакшн, то всё что не конфигурируется, будет периодически возвращаться на доработку программисту, с огромными потерями во времени. Поэтому вынос в XML подобных вещей — шаг правильный, если конечно это можно корректно вынести.
Хорошо бы ещё понимать что когда это уйдёт на продакшн, то всё что не конфигурируется, будет периодически возвращаться на доработку программисту, с огромными потерями во времени.

Вечный спор «конфигурируемость vs контролируемость».

Очевидно, решается не по принципу «если можно корректно вынести», а по оценке жизненного цикла одних и других изменений.
Что же у вас за софт такой, где нужно конечный автомат конфигурировать из XML извне?
Понятно, что параметры работы программы хорошо было бы иметь возможность менять без перекомпиляции, но менять принцип работы стейт машины… Это вы уже какой-то интерпретатор непонятно чего написали, который должен уметь делать все.
Поддерживаю. Хрен там вы вынесете логику работы конечного автомата во внешнюю хмл так, чтобы её какой-то админ мог поправить и что-то дельное вышло. Ну разве что в духе «вот сейчас у нас в демке одна логика (пропустим шаг логина, а то задалбывает каждый раз вводить), а потом в продакшене будет чуть другая (логин обязателен)». Но ничего серьёзнее.
Господа теоретики, в нашей организации подобная внешняя конфигурация логики приложения используется, причём давно и в серьёзном софте.
Среди прочих применений — можно изменить логику программы в версии, поставленной на предприятие 10 лет назад, если сейчас уже не осталось ни разработчиков, помнящих тот код, ни окружения, позволяющего *оперативно* развернуть, собрать и протестировать код 10-летней давности (с использованием тогдашних версий библиотек, фреймворков и т.д.).
Вариант 1 — у нас разное понимание понятия «изменение логики программы» и вариант 2 — у вас хороший архитектор/ведущий разработчик, спроектировавший это. Тогда любите и цените его :)
Сделали просто свой DSL.
Конфигурирование и DSL это разные вещи.
UFO just landed and posted this here
Эдак можно дойти до того что, «вот же консольное приложение, давно-давно написанное, ему на вход передаются файлы и параметры командной строки — и вот какая магия, оно обрабатывает именно эти файлы и именно с этими параметрами!». Понятное дело, если вам нужно по уже известному алгоритму преобразовывать что-то одно в другое, конфигурируя только «что», «куда» и «с какими параметрами», то тут всё ок. А вот возьмите и преобразуйте своей софтиной входящий хмл-документ в картинку формата png, меняя только конфиг.
UFO just landed and posted this here
Ну Вы же не будете утверждать, что оно преобразовывает из любого формата в любой?
Ну вообще это возможно — например, если конфиг указывает последовательность вызовов внешних трансформеров. Типичная такая шинка.
А где же здесь «состояния и переходы между ними»? Вы задаёте последовательность команд.
Во-первых, не я. А во-вторых, у вас каждое «состояние» — это преобразованный документ, а «переход» — это и есть преобразование из формата в формат.

Не то что бы я это одобрял, но это возможно.
UFO just landed and posted this here
Ну тут еще надо помнить, что для того чтобы «подправить .sh — скрипт» нужны прямые руки и что-то в голове, а вот откомпиленный сишный модуль можно запустить и он «just works».

Я вообще не противы выноса в конфиги всяких там параметров и констант, но вот когда туда пихают пол-программы, жертвуя удобством написания, отладки, скоростью, безопасностью и надёжностью — это меня смущает.
UFO just landed and posted this here
откомпиленный сишный модуль можно запустить и он «just works».
sh-скрипт — тоже, пока его не подправили.
Считаю необходимым отметить, что фактически это выглядит подобно скриптовому языку с рядом особенностей.

Ну то есть программа на программе, причем ответственность за первую переложена на плечи администратора.

Именно за это я и не люблю овер-конфигурабельные системы.
UFO just landed and posted this here
Не забываю. Проблема в том, что обычно заказчик в таких случаях если работает, говорит «вот видите, мы сами все можем», а если ломается — то «немедленно почините». При этом конфигурацию из них фиг добудешь, вали в продуктив и разбирайся сам.
UFO just landed and posted this here
К сожалению, «обычно» это фикс-прайс контракт на поддержку.

И вот сочетание этих всех вещей (ну и еще некоторого количества чисто архитектурных навыков) и заставляет меня не любить конфигурируемые приложения.
UFO just landed and posted this here
Мы с вами в этом вопросе по разные стороны баррикад, но я вас понимаю… За фикс-прайс контракт на поддержку — пусть гребут дико неудобное, но не вызывающее вопросов…
В начале 2008 меня обучали работе на дико неудобной CMS. Я думал долго — подо что же она оптимизирована? И понял — под краткость времени обучения верстальщика. Потом её много материл, реверс-ниженерил и скриптовал…
Про что и речь: вы позволяете себе «в серьезном софте» выкатить на предприятие изменение, не имея возможности его протестировать.
Тестирование изменений в бинарном коде и изменений *только* в логике программы — две разные вещи. Уже как-то маялись с поиском багов, когда изменение пары строчек и перекомпиляция (но с другой версией STL) привело к утечками памяти и сопутствующим непредсказуемым глюкам.
Вдаваться в подробности не хочу, но разумеется изменения в логике проходят тестирование на актуальной версии софта до передачи в продакшн.
Вдаваться в подробности не хочу, но разумеется изменения в логике проходят тестирование на актуальной версии софта до передачи в продакшн.

Ну то есть сделать актуальный ландшафт для кода десятилетней давности вы можете, а сделать для него же компиляционное окружение — нет?
сделать актуальный ландшафт для кода десятилетней давности вы можете
=«законсервировать» сервер приложений с интсалляшкой. Делов-то…

сделать для него же компиляционное окружение — нет
Консервировать заодно и IDE? Идея в общем-то правильная, но пробивается сильно труднее…
=«законсервировать» сервер приложений с интсалляшкой. Делов-то…

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

Консервировать заодно и IDE? Идея в общем-то правильная, но пробивается сильно труднее…

IDE-то зачем? Консервировать надо билд-скрипт и билд-систему, это немного.
> А во-вторых, это как раз нетривиально — виртуалки в образах (и любые образа систем) тухнут,

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

История из жизни: берем машину под Windows, вводим ее в домен (потому что такая конфигурация в продуктиве). Делаем снепшот. Работаем-работаем-работаем. Долго работаем. Откатываем на снепшот, чтобы сделать начисто. Результат: машина не видит домен. Причина: у машины есть доменный эккаунт, который (по умолчанию) нужно продлевать каждые тридцать дней. В снепшоте он старше.

В общем, как-то так. В деталях могу ошибаться.
Тоесть, машина «вываливается» из сетевой инфраструктуры? Понятно, спасибо.
Еще больше поддерживаю, но только я и автологин из конфига поостерегся бы делать. Ведь в демке должны быть доступны большинство (а то и все) возможностей системы. А значит надо логинится кем-то вроде админа. А потом или кто-то что-то забудет отключить, или скучающий пользователь где-то отроет нужные параметры — и разбирайся потом кто дыру в софте оставил.
Ну вообще тот, у кого есть право менять конфиг системы — это или программер, или админ — а уж они и так и так что угодно с системой могут сделать. Вопрос с «забудет отключить» решается билд-сервером, который не забудет.
Вся задача оптимального программирования — это нахождение такого алгоритма решения задачи, который минимизирует матожидание факапа от его выполнения. Учитывая, что человек (пользователь, админ, настройщик билд-сервера, бизнес-заказчик) может ошибиться — неоптимально закладывать в программу [деструктивные] возможности, не соответствующие решаемой бизнес-задаче.

Уж если надо провести автоматизированное тестирование — лучше сделать отдельный тестовый билд, а ещё лучше — написать юнит-тест (код которого точно не попадёт в боевую систему). А нормальное тестирование проводить на стенде с функционалом, идентичным боевому.

Тут можно вспомнить кучу громких багов, тот же Ariane 5, связанные с неадекватными ожиданиями программистов относительно того, как квалифицированно будет использован их рабочий код.
Вы очень серьёзно подходите к качеству ПО. А вон выше люди (не программисты даже) в продакшене прямо конфиги правят на лету, в которых алгоритмы в хмл-е написаны.
картинка с Васей в кругу друзей — зачет! чуть не задохнулся от смеха (:
А ещё у Васи блокирующая анимация. Гореть ему в аду.
И не нужно брать пример с Mac OS X — там она тоже криво сделана.
Я часто использую автоматы, а иногда даже приходится Марковские Цепи. При этом чтобы код оставался красивым и понятным, чтобы удобно было расширять автомат, надо писать свой builder, фактически DSL. Да, XML и json в данном случае — зло.
Да, спасибо, что напомнили, что надо не только писать не только специфичный метод (или реализатор интерфейса) stateA_switch1() (а лучше
private static Switcher STATE_A_SWITCH_1 = new Switcher(State.A));
, но и setStateB() и unsetStateA() (лучше тоже в виде реализаторов интерфейсов, а не через рефлексию, чтоб IDE лучше хэндлила).
Почитал по местной наводке это… Подумалось, что в таком разрезе эволюция SM обещает повторить эволюцию ORM…
UFO just landed and posted this here
UFO just landed and posted this here
Sign up to leave a comment.

Articles