Previous Entry Share Next Entry
photo24

(repost) Про ёжика в тумане, зазнайство, языки программирования и вериги

Оригинал взят у vit_r в Про ёжика в тумане, зазнайство, языки программирования и вериги
Читать стоящее ниже не надо. Тем, кто прочитает, счастья в жизни это не принесёт. Короче, я предупредил.

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

Про вправление мозгов



Арчибашев Описание мира в конечных автоматах, таблицах переходов и сообщениях - это модель.

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

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

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

Работа с сообщениями



Первым делом, конечно, стоит разделить «можно» и «нужно», Я видел разбор строк, построенный на конечных автоматах и сообщениях. Естественно, это не представляло из себя пример рационального использования вычислительных мощностей.

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

Но, главное, деление системы на домены становится совершенно элементарным. При этом смена доменов вплоть до языка программирования перестаёт быть нерешаемой задачей.

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

Первый навык, которому учится аналитик - умение делить мир на независимые части. Причём, на самом деле независимые, а не так, как это принято в индустрии.

Конечные автоматы



Все программы можно представить в виде конечных автоматов.

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

Обычный студент приходит на фирму и делает кучку кода. Потом ещё одну. И ещё. Постепенно он мужает, обрастает бородой и пузом, набирается опыта... Он может без особого напряжения произвести большую кучу, или с удовольствием покопаться в чужой. Если он любопытен и честолюбив, он учит много ненужных слов и бесполезных понятий, строит на корреляциях причинно-следственные связи, выводит из частного общее, возводит закономерности на предвзятой выборке случайных совпадений и становится гуру.

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

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

Также плоский конечный автомат плохо помещается в голове, когда растёт количество овалов и стрелочек. Рост очень нелинейный и приходится делить и упрощать, просто чтобы с состояниями и переходами можно было работать нормально.

Диаграмма классов на пол стены или хитрый автомат из Рапсодии со сложными вложениями могут вызвать морщенье лба только у подготовленных софтверных дизайнеров. У остальных - сразу испуганные глаза и желание поскорее сменить тему. Плоские конечные автоматы понимают даже люди из маркетинга. Нормальные несофтверные инженеры схватывают всё налету.

Самое обидное, что при этом даже постороннему человеку прекрасно видно, как что работает и хорошо это сделано или бездарно.

Второй навык, который вырабатывают те, у кого на это есть мозги и желание, - это умение упрощать мир.

Освоить это чрезвычайно сложно. Но потом многое получается на автомате. В частности, когда в требованиях проблемы, или программисты делают непонятно что, я раскладываю use cases на автоматы и сразу становятся понятны как пути нормальной работы, так и условия обработки отказов. Причём, на диаграмме всё видно сразу, так что для общего анализа это гораздо удобнее штанов Кокбурна.

Таблицы переходов



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

Я о таблицах писал, так что повторяться не буду. Кто хочет, вспомнит. Кто не помнит, найдёт. Да и книжку почитать тоже иногда не помешает. Здесь расскажу только о неполных таблицах.

Возьмём банальный пример.

if( A ) {
  if( a) {
    X ;
  } elsif( b) {
    Y ;
  }
} elsif( C && a) {
  А ;
}


Казалось бы, это выглядит так:
    | a | b |
----+---+---+
  A | X | Y |
----+---+---+
  C | А |  
----+---+


Первая строчка - сигналы, первая колонка - состояния. Всё просто.

Всё просто было бы, если бы это было правдой. Но так видит мир нормальный программист. На самом деле таблица гораздо сложнее.

    | a | b | c | d |  ...   | q |
----+---+---+---+---+- ...  -+---+
  A | X | Y |   |   |  ...   |   | 
----+---+---+---+---+- ...  -+---+
  B |   |   |   |   |  ...   |   |
----+---+---+---+---+- ...  -+---+
  C | А |   |   |   |  ...   |   |
----+---+---+---+---+- ...  -+---+
..................................
----+---+---+---+---+- ...  -+---+
  X |   |   |   |   |  ...   |   |
----+---+---+---+---+- ...  -+---+
  Y |   |   |   |   |  ...   |   |
----+---+---+---+---+- ...  -+---+


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

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

И не только потому, что ему лень и страшно. Он не умеет делить мир на подсистемы. Он не умеет упрощать. Так что мозг автоматически блокирует информацию, которая может ошарашить. Так что он рисует стрелочки. Или просто пишет в код, стараясь не вылезать на более высокие уровни и не задаваться опасными вопросами.

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

1. Стрелочка на самом деле должна быть, просто её забыли нарисовать.

2. Сообщение пришло, сообщение может приходить, но его можно просто игнорировать. Если пользователь заполнил формочку и нажал кнопочку, мы начали её обрабатывать. Если он жмёт второй и третий раз, мы не дёргаемся. Пишем в таблицу I for Ignore.

3. Это сообщение в этом состоянии прийти не может. Мы проверяем пин-код в банкомате, а тут нам сваливается очередной набор цифр. Это уже проблема. Возвращаем карточку, отключаем пользователя, закрываем терминал и зовём на помощь. Пишем E for Error.

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

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

Конечно, делая таблицу, сложнее забыть стрелочку, так что поведение системы становится более определённым. Иногда пустая клетка приводит к нескольким часам обсуждения.

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

Мир первого выглядит так.

    | a | b | c | d |  ...   | q |
----+---+---+---+---+- ...  -+---+
  A | X | Y | I | I |  ...   | I | 
----+---+---+---+---+- ...  -+---+
  B | I | I | I | I |  ...   | I |
----+---+---+---+---+- ...  -+---+
  C | A | I | I | I |  ...   | I |
----+---+---+---+---+- ...  -+---+
..................................
----+---+---+---+---+- ...  -+---+
  X | I | I | I | I |  ...   | I |
----+---+---+---+---+- ...  -+---+
  Y | I | I | I | I |  ...   | I |
----+---+---+---+---+- ...  -+---+


Второй просто на уровне рефлексов строит совершенно другое.

    | a | b | c | d |  ...   | q |
----+---+---+---+---+- ...  -+---+
  A | X | Y | E | E |  ...   | E | 
----+---+---+---+---+- ...  -+---+
  B | E | E | E | E |  ...   | E |
----+---+---+---+---+- ...  -+---+
  C | A | E | E | E |  ...   | E |
----+---+---+---+---+- ...  -+---+
..................................
----+---+---+---+---+- ...  -+---+
  X | E | E | E | E |  ...   | E |
----+---+---+---+---+- ...  -+---+
  Y | E | E | E | E |  ...   | E |
----+---+---+---+---+- ...  -+---+


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

Каждая E может быть не учтённой стрелочкой. Цена вопроса такая же. Может быть, плюс время на выбор варианта или на исправление модели состояний.

Каждая I, которая на самом деле не I, - это приглашение к долгим увлекательным приключениям.

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

Про цену, которую мы или не мы платим



Самая любимая отговорка тех, кому лень или недоступно, - это про цены и отсутствие специалистов.

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

Людей умных много, научить можно. Да, шесть месяцев и отсев, но результат того стоит. Тем более, можно брать любых специалистов, лучше всего нормальных инженеров или просто людей с головой. Код по дизайну набить - это потом можно нанять даже индусов, благо всё определено и описано теми, кто может думать.

Насчёт второго - всё очень просто и очень хитро.

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

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

Если сковородка может сломаться через пол года, можно взять дешёвую сталь, простое покрытие и китайских рабочих. Если нужен срок жизни в десять лет, то придётся брать хорошие материалы, дорогие технологии и made in Germany.

Если мы можем игнорировать, что от сайта отваливается один пользователь из тысячи, можно быстро сварганить что-то простое. Если потеря одной финансовой транцакции грозит штрафом на пол миллиона, придётся подробно продумывать архитектуру, выбирать надёжные библиотеки и серьёзно заниматься тестированием.

Но при этом «быстро и просто» не значат «плохо».

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

И тут надо вспомнить об игнорируемой всеми хитрости.

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

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

Пользователь вылавливает данные, заливает в Excel и исправляет ручками. Но это его время и его проблемы.

Заказчик терпит убытки из-за дефектных компонентов и открывает у себя отдел тестирования, ухлопывая десятки человеколет на то, предотвратить что мы могли бы, вложив один человекомесяц. Но это наши деньги, а то - его.

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

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

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

Copyright

(CC BY-NC-ND 3.0) vit_r, 2013

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
Перевод на английский запрещён, потому как нефиг портить хорошую вещь.



  • 1
smalgin June 21st, 2013
Колумб Америку открыл, страну для нас совсем чужу-ю!
Дурак! Зачем он не открыл на нашей улице пивну-ю!

ufm June 21st, 2013
Как люди без ерланга-то мучаются.

vit_r June 21st, 2013
Видел я, как гуру объяснял начинающему программисту, как вся система целиком работает. Так что не известно, кто больше мучается.

С Эрлангом, кстати, различия минимальны. Без разницы, хранить состояния в объекте или таскать в сообщении. Правда переход от одного представления к другому несколько шизофреничен.

maxim June 22nd, 2013
Ну понятно, эрланг хуйня, а матрицу буквочками E заполнять -- это круто :-)

vit_r June 22nd, 2013
Ну почему сразу истерика? Кроме "Му-му" есть ещё масса прекрасных книжек.

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

buriy June 21st, 2013
Увы, никакой секретной технологии тут нет.
По-моему, программистов этому должны в обязательном порядке учить на первом-втором курсе вуза.
У нас в НГУ учат.
Математиков тоже этому учат, но уже в курсе мат.логики.
Физики тоже этому учатся, когда ставят эксперименты и сортируют по важности причины, которые могли привести к тому или другому эффекту.
Так что я даже не знаю, насколько человек должен быть дурак, чтобы этот навык не получить или не уметь применять.
Разве что, если он "паковщик", ему всегда "лень разбираться", и он предпочитает исправлять всё по-простому, и не собирается понимать, как что работает, и строить карту. В общем, статья очень сильно напоминает переизобретение Programmer Stone -- ещё в 99м году объяснили, откуда берутся плохие программисты!

fenikso June 21st, 2013
>Но мысль о том, что можно просто нарисовать таблицу и методично пройти по всем вариантам, просто не приходит ему в голову.

:)

109 June 21st, 2013
ну ты-то, я надеюсь, понимаешь, что всё это хуйня? :)

таблица на самом деле не двумерная, а N-мерная, где N >> 3. просто многомерную таблицу на бумаге не нарисовать, и в голове не удержать.

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

vit_r June 21st, 2013
Размерность таблицы - это результат работы аналитика. Кто может, делает двумерные и простые, кто не может делает кашемерные и утверждает, что другого ничего не получится.

Конечные автоматы - это как таблица умножения. Знать надо, но владеть только ими для дела не достаточно.

И представление должно быть не удерживаемым в голове, а обозримым на всех уровнях. Впрочем, это немного другая история.

(Deleted comment)
justy_tylor June 21st, 2013
Удивительно дремучая хуйня.

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

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

vit_r June 21st, 2013
Ох. Естетсвенно есть технологии, позволяющие строить из конечных автоматов большие работающие системы. Только получают их усилиями мозгов, а не разбиение.

Плюс нам не нужна корректная система. Достаточным условием является то, чтобы она не выдавала ошибочный результат.

sab123 June 21st, 2013
Представлять все в виде автоматов и сообщений - самый кривой и глюкопроизводящий способ разработки. В этом плане эпической вершиной является язык MUSKOX: ftp://ftp.iecc.com/pub/file/muskox.ps.gz‎

_winnie June 21st, 2013
Какой ужас, столько букв, чтобы сказать "не забывайте продумать default в switch-case", банальность "Надо делить на подсистемы. Правда вы это не умеете, а я умею" и спорный подход "мыслите только сообщениями". Всё остальное - мега-ЧСВ.

Edited at 2013-06-21 11:44 pm (UTC)

maxim June 22nd, 2013
Так на чем писать автор предлагает ?

  • 1
?

Log in

No account? Create an account