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

Jun 21, 2013 00:53

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Освоить это чрезвычайно сложно. Но потом многое получается на автомате. В частности, когда в требованиях проблемы, или программисты делают непонятно что, я раскладываю 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



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

management, it, economics, ru, qa, motivation, quality

Previous post Next post
Up