3. Инженерный процесс
Тренды современной системной инженерии
В системной инженерии SoTA (state-of-the-art, современное состояние метода, лучшие на сегодняшний момент варианты метода из всего их разнообразия) меняется довольно быстро: если брать программную инженерию, то технологии там заменяются практически полностью каждые 4-5 лет, хотя дисциплины computer science и методология в варианте специализации engineering science до software engineering science, которые поддерживаются этими технологиями, выдерживают в своих основных чертах немного дольше.
Программная инженерия (и тесно связанные с ней инженерия систем машинного обучения, инженерия данных, инженерия систем искусственного интеллекта) по части трендов занимает особое место в системной инженерии: поскольку там имеют дело главным образом с информационной работой, в которой не нужно тратить много энергии и времени на перемещение вещества в порядке изменения физического мира, а нужно только менять состояние носителей информации, пробы и ошибки там проходят быстрее, чем во многих других видах инженерии, где дело почти сразу доходит до медленных физических процессов в физическом мире и «пробы и ошибки» (trial-and-errors) делать медленнее. Поэтому программные инженеры быстрее находят новые удачные способы ведения инженерной деятельности. Замечено, что методы, которые становятся повсеместными в программной инженерии, появляются в классической инженерии киберфизических систем где-то через 10 лет, и получают распространение через 15 лет от того момента, когда они впервые были замечены в программной инженерии.
Так, именно в программной инженерии появились методы agile и эволюционной инженерии как противопоставление водопаду с его однократным прохождением жизненного цикла. За последние пять лет нормой инженерного метода в программной инженерии стало не просто создание систем, но создание и развитие, эволюционная/непрерывная инженерия (подробней об этом рассказано в нашем руководстве). Конечно, это уже активно обсуждается в инженерии киберфизических систем, но только малое число предприятий перешло на новые инженерные agile процессы, это особо хорошо заметно по происходящему в ракетостроении: успехи предприятий с agile процессами не сравнить с успехами (вернее, неуспехами) предприятий с классической разработкой.
В системной инженерии киберфизических систем, где есть и программная инженерия, и «железная» инженерия, продолжалось движение в сторону общности инженерной работы для систем самой разной природы, включая выход в работу с сетями и системами с людьми (движение в сторону систем систем). В таких компаниях новинки в инженерном процессе программного обеспечения более быстро воспринимаются в «железной» части.
Таким образом в современных учебниках программной инженерии учат эволюционности инженерии, а в учебниках классической системной инженерии обсуждают безмасштабность, роль системных инженеров в проектах систем самой разной природы (несмотря на продолжающийся акцент на классике систем аэрокосмической и транспортной инженерии, но уже явно звучат призывы внимательно смотреть на системы другой природы), создаваемых на самых разных уровнях масштаба.
Наше руководство снимает это различие, предлагая версию одновременно безмасштабной и эволюционной системной инженерии. Это наш вклад в развитие инженерной науки.
Главный тренд в развитии программной инженерии сейчас — это переход к разработке с использованием AI-copilot, причём сначала это был pair programming (программирование вдвоём, парой — но за клавиатурой один человек, другой помогает думать. За клавиатурой — AI-copilot, а человек помогает думать, Software 3.0, или vibe coding1, как его определил Andrej Karpathy), а затем — peer programming, когда часть работы берёт на себя AI-агент, сначала автономно выполняющий довольно большие задачи, а потом и берущий на себя решение проблем. Это отражает переход от поддержки AI в части software design, понимаемого как «проектирование кода и кодирование» к поддержке AI полного software process: постановке задачи на очередной инкремент, а затем полностью вся разработка, включая методологическую и архитектурную проработку, проектирование/design и кодирование/coding, оптимизационное компилирование в машинный код, юнит-тестирование в части инженерного обоснования (quality assurance), сборку/интеграцию, системное тестирование (включая архитектурное и безопасности), разворачивание/deployment, введение в эксплуатацию (delivering), мониторинг, получение пользовательской обратной связи (feedback) — и всё это непрерывно/continuous в ходе непрерывной разработки.
В классической инженерии ровно то же самое, за исключением немного другой терминологии того, что называют design/проектирование. Software design чаще всего включает в себя методологические рассмотрения по видам применимых прикладных алгоритмов (из предметной области применения программы — какой процесс в реальном мире поддерживает программа, чаще всего это DDD, domain driven design, когда объекты программы впрямую отражают сущности предметной области применения программы, например, объект invoice/счёт программного кода и базы данных поддерживает объект invoice/счёт реального мира). Design в инженерии — это работа с CAD, создание конструкции, на которую разложены функции системы, причём в русском языке это будет даже два метода работы (практики инженерии), обозначаемые двумя словами: конструирование как создание деталей с их сложной формой и проектирование как указание, как из деталей собирается всё изделие. Это довольно тонкое различие, но инженеры-проектировщики (проектирующие системы из каких-то уже сконструированных других систем — деталей или готовых других модулей-систем) и инженеры-конструкторы в отечественном машиностроении различаются (при вечных спорах, что часто конструктор занимается не только конструированием, но и проектированием, то есть работает и на уровне составных частей конструкции, а не только на уровне отдельных деталей и косного вещества), в западном — не различаются.
Всего же можно выделить для AI-поддержки в программной инженерии разные поколения, обозначаемые Software 1.0, 2.0, 3.0, а сейчас даже можно говорить и о 4.0 (о них подробнее говорится в руководстве по интеллект-стеку в разделе «Алгоритмика»). Софт/software тут сокращение от software engineering:
-
Софт/software 1.0, классическое программирование: основано на явном кодирования людьми правил и инструкций на языке программирования.
-
Софт/software 2.02, differentiable programming: программы дифференцируемы3, поэтому способны обучаться на основе данных (обычно большой объём данных) и адаптироваться к новым ситуациям. Наиболее распространённая и известная форма дифференцируемых программ — это нейронная сеть, которая может аппроксимировать практически любой алгоритм.
-
Софт/software 3.04: Основано на предварительном обучении нейронных сетей в форме больших языковых моделей (large language models, LLM), обученных программировать. Эти модели понимают и программный код, и естественный язык, поэтому им можно давать в том числе и задания найти ошибку в коде, поменять этот код для получения каких-то новых свойств программы. Обычно это или AI-copilot (парное программирование, «второй пилот за штурвалом» и как раз к этому случаю применимо vibe coding), или более-менее автономный AI-агент (самостоятельное выполнение задач «под ключ» по поручениям). Заметим, что в этом варианте вполне присутствует способность к творчеству, ибо написание кода может идти методом проб и ошибок, задействуется меметический алгоритм (в этом случае говорят о reasoning/thinking/«scaling up test-time compute») для получения новых результатов, возможно, недоступных для человеческого мышления.
-
Софт/software 4.0 — можно ожидать, что тут будет инициатива агента на выполнение задач: агент будет выполнять и постановку задачи (например, брать обратную связь у пользователей и определять, что ему надо программировать, чтобы развивать систему в сторону её успешности), и программировать, и выводить самостоятельно инкремент системы на введение в эксплуатацию.
В необязательно программной, а именно — системной инженерии, «просто инженерии», мы можем наблюдать те же поколения по отношению к system design (проектирование+конструирование):
-
Engineering 1.0: классическая архитектура и design (прежде всего конструирование уровня детали с использованием CAD и имитационного моделирования для расчётов прочности, теплопроводности и т.д.).
-
Engineering 2.0: «дифференцируемое всё»5 (в software 2.0 это было дифференцируемое программирование), например, можно дискретное представление архитектуры сделать непрерывным в так называемом «латентном пространстве» архитектурных решений, а затем найти оптимум — и вернуться в дискретное представление, получив оптимальную архитектуру. Важно, что тут не используются представления на естественном языке, используются представления на формальных языках, но вот операции с ними могут делаться в «латентном пространстве», чтобы иметь возможность задействовать оптимизационные методы вычислительной математики (например, метод стохастического градиентного спуска, SGD6). В программной инженерии Andrej Karpathy сказал в 2017 году, говоря о Software 2.0: «Gradient descent can write code better than you. I’m sorry»7. Это полностью относится и к engineering 2.0, только вместо code надо подставить проект/design системы.
-
Engineering 3.0: это использовать программирование на естественном языке, формализацию и оптимизацию в рамках этой формализации при этом делает «компилятор» так же, как при компиляции кода с формального языка программирования в машинный код. Тут просто добавляется ещё ступенька — формализация делается тоже машиной, CAD-AI-copilot для pair engineering (аналогично парному программированию8 в программной инженерии) и CAD-AI-agents для peer engineering (аналогично peer programming, отражает «равный статус программиста» для AI-agent). В инженерии «железа» или электрики всё ровно так же, как используется AI-copilots и AI-agents для программистских IDE9.
-
Engineering 4.0: агент инициативно ставит инженерную задачу, которую осмысленно решать, тратить на неё ресурсы, далее — работает агент по решению задач, как в Software 4.0.
На каждом уровне стека масштаба систем для систем разной природы их особенности дают огромное разнообразие трендов в инженерных методах. Общие для всей системной инженерии тренды найти сложно, хотя тренды движения к эволюционной и безмасштабной инженерии общие. Совсем не все инженерные проекты осознанно следуют этим трендам, но кто им не следует — быстро покидает рынок. Мы условно можем разбить общие для инженерии тренды на два вида:
-
Тренды концепций целевой системы (концепция системы — это каким образом функциональная организация системы будет отражена её конструкцией). Скажем, в радиоэлектронике это ориентация на микропроцессоры со всё более жёсткими проектными нормами, например, стремительный по историческим меркам прогресс проектных норм в компании TSMC10, или на использование GPU или TPU, или переход на новые типы ускорителей вычислений для отдельных видов вычислений (сейчас ожидается примерно через пять лет повсеместное применение квантовых компьютеров и оптических вычислителей). В киберфизических системах, особенно в классической робототехнике — это переход на управление на основе искусственных нейросетей. В работе с внутренними состояниями личности это переход к представлениям функционализма, а также переход к представлениям когнитивной революции. В основном это разбиралось в руководстве по системному мышлению.
-
Тренды инженерного процесса, то есть методов создания и развития систем, то есть тренды в сервисах организационных систем, которые обычно и служат системами создания. Например, эволюционность инженерии вместо жёстко организованной стадийной водопадной одноразовой разработки — и в программной инженерии, и в практически любой инженерии. С первого раза правильно — но MVP, затем бесконечное развитие системы, сегодня инженерный процесс формулируется примерно так, это было показано в руководстве по методологии. Это дало не только распространение разного сорта вариантов инженерии внутренней платформы разработки (ранее — DevOps и SRE) как способов непрерывной быстрой сборки результатов разработки, а также быстрого обоснования успешности и введения в эксплуатацию. Это дало ещё и возможность непрерывной подстройки бизнесов под меняющиеся потребности клиентов и возможности команды проекта (обсуждается как движение Lean Startup после выхода книги Eric Ries «The Lean Startup» в 2011 году, об этом будет подробней дальше в нашем руководстве). Ещё пример — выход моделирования на стадию эксплуатации, то есть использование цифровых двойников как цифровых моделей, которые отслеживают состояние целевой системы на стадии её эксплуатации. В психотерапии (терапия — это аналог ремонта в инженерии личности) происходит отказ от методов психоаналитиков в силу появления evidence-based методов cognitive and behavior science как «золотого стандарта психотерапии»11. В случае методов политики как инженерии общества замена SoTA происходит очень медленно, но тренд очевиден — замена всевозможных диктатур и монархий на более демократические (бескровная смена правителя) формы правления, а также отделение церквей от государства. Хотя тут можно и поспорить: это тренд изменения концепции целевой системы или тренд методов работы создателей из их графа — ибо из одних и тех же людей в обществе мы берём и создателей, и самих членов создаваемого, развиваемого и даже работающего уже общества.
А есть ли тренды концепций использования? Конечно, но в целом потребности людей остаются неизменными: «спасение» (всё, что ведёт к бессмертию), «путешествия» (летать, свобода перемещения), «познание» (обычно в целях спасения и путешествий), делегирование труда. Поэтому функции систем остаются более-менее одни и те же (скажем, у транспорта — перемещение грузов и пассажиров из точки А в точку Б), а вот концепции автомобильного и ракетного транспорта будут разными, пилотируемого и беспилотного — разные, равно как будут разные и инженерные процессы в автомобилестроении и ракетостроении при всей их общности на высоком уровне абстракции.
Тренды концепции целевой системы обычно учитываются в более прикладных инженерных руководствах/регламентах/стандартах по разработке систем той или иной природы. В строительной инженерии учитывают тренды в конструкции зданий, в программной инженерии — тренды в софте (например, появление программ для квантовых вычислений на квантовой аппаратуре). Есть тренды в методах работы, которые настолько привязаны к специфике целевой системы, что их можно учесть только в прикладных очень узких курсах/руководствах/регламентах/инструкциях, например использование методов CRISPR и аналогичных в генной инженерии. Такими узкими прикладными методами являются и spacing и interleaving как методы подачи учебного материала в инженерии мастерства (эти методы обсуждались в начале руководства по системному мышлению, а также они даются в наставлениях по инженерии личности).
Тренды организации инженерной работы, то есть тренды в создании и эксплуатации организационной системы (оргзвена, предприятия, проектной группы, «расширенного предприятия»/«проектной кооперации» какого-то крупного инфраструктурного проекта, и т.д.) обычно рассматриваются в руководствах/стандартах/регламентах/блогпостах по системному менеджменту, а не системной инженерии.
И всё-таки, чтобы подчеркнуть мысль об общности нормативной инженерной науки для всех родов инженерии, приведём примеры нескольких общих трендов, которые нужно учитывать в сегодняшней работе инженеров во всём многообразии их ролей и всём многообразии целевых систем:
-
Ведущий тренд — это использование в инженерии AI, а также получение систем (которые всё чаще и чаще — роботы, или системы из людей) путём не просто изготовления, а изготовления и обучения. Но мы это только что разобрали чуть подробней. Это главный, ведущий тренд. Так, порождающее проектирование (generative design) — это использование компьютеров для проектирования, в том числе в последнее время и для разработки концепции системы, и для предложения архитектуры12. Подтренд в этом порождающем проектировании, который только-только оформляется — это выучивание функциональности автономных систем в специально сконструированных для этого виртуальных мирах, world models13. Дело в том, что сегодняшние киберфизические системы имеют инженерный процесс, похожий на процесс создания зверей: рождается «железо» или «мясо» (при всей неполиткорректности такого названия) с какой-то рудиментарной «прошивкой», а затем происходит обучение в ходе какой-то игры с реальным миром — звери учатся ходить и бегать, охотиться, управлять своим телом, а роботы учатся тоже управлять своим телом в виртуальном мире, а потом это мастерство переносится в реальный мир. Уже не надо писать «программу робота», эту «программу робота» (а любая киберфизическая система по факту — робот) не нужно порождать софту-разработчику, но универсальная программа «искусственного интеллекта» выучивается выполнять какую-то работу в специально созданном для неё виртуальном мире, а потом переносится в реального робота — и всё работает. Автомобиль с нейронной сеткой в его системе управления учится автономному вождению или домашний робот учится вытирать грязные столы в виртуальном мире с точным физическим моделированием, после чего результирующая обученная программа нейронной сети переносится в реальный автомобиль или робот — и всё будет работать14.
-
Повышенное внимание к экологии. Нормативы на загрязнение окружающей среды растут, поэтому строго контролируются различные выбросы в атмосферу, в реки, ограничивается использование токсичных материалов (например, запрещён асбест) — это важно для крупных инженерных объектов, для атомных станций даже иногда возникают парадоксальные ситуации, когда можно брать воду для охлаждения из местных источников, но нельзя потом эту воду в них сливать: у источников естественная радиоактивность больше, чем разрешается для сброса воды от атомной станции! Но и для медицины и даже пищевой промышленности нормативы на ядовитость их целевых систем и используемые «материалы» тоже ужесточаются. Можно спорить, надо ли отслеживать выбросы двуокиси углерода в атмосферу в части их потенциального влияния на климат, ожидает ли нас глобальное потепление или очередной малый ледниковый период, но тут как с гимном: когда Михалкову сказали, что его поэзия для гимна плоха, он ответил: «Плоха или хороша, это неважно. Но когда гимн заиграют — ты встанешь». У инженеров тоже так: они выполняют требования политиков, а требования политиков становятся жёстче.
-
Повсеместный переход к эволюционной инженерии и agile методологиям от водопадных. Это мы тоже довольно подробно обсудили, и тут много разных нетривиальных следствий. Например, малый размер инкремента/фичи, проходящего весь путь от замысла до выпуска, максимальная независимость разработки инкрементов друг от друга (этим озабочены архитекторы проекта). Часть этого тренда — параллельная инженерия, когда традиционные стадии водопадного жизненного цикла выполняются параллельно, а не последовательно (скажем, начинаем рыть котлован, строим фундамент одного крыла здания, продолжаем рыть котлован, возводим крыло, в этот момент строим фундамент второго крыла здания, заселяем первое крыло, в этот момент строим второе крыло здания — а то, что оба крыла будут крыльями одного и того же здания обеспечит информационная модель и точность возведения: совпадут все дверные проёмы, все коммуникации, окна везде будут на одинаковой высоте. В принципе, и проектировать эти крылья здания можно было бы не одновременно, а ещё важно, что здание не прекращает модифицироваться даже после окончания основного строительства, адаптивная архитектура15, адаптивная строительная архитектура тут — синоним эволюционной). Это не только тренд, лежащий в основе эволюционной инженерии («не пытайтесь сделать всю систему целиком одним куском, обеспечивайте в ней фичу за фичей постепенно, подстраиваясь под меняющееся окружение и используя всё новое и новое знание, появляющееся в ходе длинного проекта»). Этот малый размер инкремента помогает ускорить работы, ибо соответствует малой порции работы (small batch size), тренду в операционном менеджменте (об этом уже было сказано в руководстве по рациональной работе, но ещё будет повторено в части операционного менеджмента руководства по системному менеджменту). В инженерии киберфизических систем это появляется после успеха такого сорта подходов в программной инженерии. В социальной инженерии малый размер инкремента был давно известен (поправки к законам, а не перевыпуск полного законодательства время от времени). Интересно, как этот подход медленно проявляется в образовании: болонская система, в которой вы можете уточнить программу через четыре года обучения в бакалавриате, а потом доучиться до магистра по выбранной специальности вместо пяти-шестилетнего обучения в специалитете «в один заход» — это отражение того же тренда, и (как это обычно бывает с трендами) тут часты откаты к более архаичным методам («специалитет» в России). Этому тренду малого размера инкремента противостоит идея «сложной смеси работ принципиально разного масштаба», ибо математика и идеи операционного менеджмента в части small batch size, использующаяся в том числе в agile методологиях инженерии, примерно соответствует математике и идеям многослойных систем управления, которые в своих работах обсуждают Matni Nicolai со товарищи16, но массовое обсуждение этих идей и математики только-только начинается, нельзя пока считать это «трендом». В любом случае, ход на математические описания против суеверий-эвристик — он выигрышный, у него большие шансы стать реальным трендом.
-
Моделеориентированность против документоориентированности — это тренд перехода к формальным (структурированные данные) компьютерным машиннообрабатываемым моделям представления инженерной информации вместо бумажных документов. В инженерии это переход к использованию информационных 3D-моделей вместо томов бумажной инженерной документации или даже переход от машинночитаемых, но не машиннообрабатываемых документов к машиннообрабатываемым (например, переход от использования бумажных документов с финансовой информацией сначала к .pdf файлам и банкам данных с этой же информацией в машинночитаемой, но не машиннообрабатываемой форме, а затем к использованию машиннообрабатываемых записей данных и даже баз данных с этой информацией. Банки данных и базы данных различаются как раз этой «машиннообрабатываемостью», часто говорят о «структурированной информации» при этом). В социальной инженерии это переход к использованию баз данных вместо архивов бумажных документов и пересылки выписок из этих баз данных в электронной форме вместо работы с бумажными документами. Нужно учитывать, что в данном случае существенно сдвигается баланс власти: один человек-чиновник при хорошем использовании компьютерных средств организации его работы может отследить выполнение бо́льшего количества ограничений свободы деятельности бо́льшего числа граждан, хотя время граждан может существенно экономиться на получение всяческих справок — но в целом мы получаем общество тотального надзора за жизнью граждан, «полицейское государство». Хорошо ли это? John Doyle (один из соавторов работы по многослойным системам управления из предыдущего пункта) говорит о «госнадзоре» и «силовиках» как об иммунной системе, защищающей от паразитов, но неизбежные следствия тут — самые разные аутоиммунные заболевания сообществ, обществ и даже человечества в целом, а также хак/взлом паразитами самой иммунной системы, вот это самое «полицейское государство» без права на творческое и продуктивное инакомыслие (мемо-иммунная система удаляет все неизвестные ей мемы/идеи и изолирует или даже уничтожает их носителей, включая потенциально полезные новые мемы и порождающих их людей и группы таких людей-новаторов, как несущих потенциальную угрозу: шанса эволюции что-то оптимизировать дальше при этом нет, «всё новое — инородно, иммунитет должен защищать от всего инородного»).
-
Цифровые двойники, их применение сводится к моделеориентированному представлению (параметры модели в виде машиннообрабатываемых данных) и калибровке численных моделей системы по актуальным данным в ходе её эксплуатации, то есть цифровой двойник рассматривается уже за пределами разработки и изготовления. Раньше говорилось о важности цифрового моделирования системы в ходе её разработки и изготовления, но цифровой двойник показывает, что время эксплуатации не менее важно в части моделирования (например, можно принимать для киберфизических систем решение не просто о плановом ремонте, но ремонте только по состоянию — и для этого нужно накапливать данные об изменении состояния системы в ходе её эксплуатации). Интересно, что концепция цифрового двойника широко распространилась за пределами традиционных в инженерии киберфизических систем: говорят о цифровом двойнике пациента, цифровом двойнике студента, цифровом двойнике клиента бизнеса, цифровом двойнике предприятия. Центральное тут — численное моделирование, включая использование нейронных сетей для получения суррогатов точных моделей и намечающееся использование квантовых компьютеров для моделирования. Численное моделирование было широко распространено в физике и оттуда пришло в инженерию веществ (например, расчёты прочности), оттуда оно (в меньшей мере) перешло в инженерию киберфизических систем и стало известно там под названием «системное моделирование», ибо под «системностью» понималось объединение самых разных физических моделей, отражавших разные «системные аспекты» в одной мега-модели. Но это не было ещё современное системное многоуровневое моделирование (которое в физике называется многомасштабным моделированием), которое начало появляться в инженерии только в последнее время (скажем, для моделирования добычи нефти моделируется поведение нефти между песчинками пласта, частей пласта как пропитанных нефтью небольших объёмов песка, пласта в целом как какой-то сложной пространственной формы в недрах из пропитанных нефтью объёмов песка). В любом случае, численное моделирование по мере распространения вычислительной техники стало применяться практически повсеместно. Основной современный тренд в этом моделировании — использование машинного обучения (аппроксимирующих различные функции универсальных алгоритмов, которые обучаются этой аппроксимации на каких-то исходных данных), в частности глубоких нейронных сетей. Это моделирование используется для систем практически любой природы, находящихся на самых разных системных уровнях.
-
«Платформизация» понимается чрезвычайно широко, но в общем случае означает наличие модуля-платформы с чётко определённым интерфейсом, который поддерживает набор специализированных/прикладных модулей для каких-то сервисов, отнюдь не все из которых нужны для каждого конкретного случая использования. В какой-то мере это следствие тренда на стандартизацию интерфейсов. Важно, что чётко определённый стандартом, выполнение требований которого легко проверить, интерфейс модуля-платформы позволяет разрабатывать прикладные модули разработчикам, организационно внешним по отношению к разработчикам платформы. Платформа автомобиля позволяет навешивать на неё двигатели разной мощности, салоны разной степени роскошности отделки, автоматику разной степени автономности работы — но все они используют общее автомобильное шасси, давая на выходе абсолютно разные по характеристикам автомобили. Платформа магазина интернет-приложений для смартфонов даёт возможность разработки приложений для десятков тысяч фирм и отдельных разработчиков. Мастерская инженеров-менеджеров реализует концепцию личности с сильным интеллектом как платформы: фундаментальное базовое образование (в которое включается и получение мастерства системноинженерной работы по нашему руководству) даёт мыслительное мастерство усиленного интеллекта, а на эту платформу легко добавить какой-нибудь модуль прикладного мастерства (например, инженерии личности или системного менеджмента). Часть этого тренда — стандартизация интерфейсов (открытая архитектура, open architecture). Нет стандартного интерфейса — не платформа! При разработке все интерфейсы между модулями не столько разрабатываются специально для каждого проекта, сколько берутся готовые — ориентация на «платформу со стандартным интерфейсом». Это в общем случае существенно снижает стоимость как проектирования (не нужно проектировать соединения), так и изготовления (можно использовать готовые модули, COTS17). Готовые системы (COTS, commercial/consumer off-the-shelf) вместо специально сделанных на заказ по индивидуальному заказу — тоже «платформенны», хотя такой взгляд и контринтуитивен. Если это одежда, то просто делается готовая всех размеров (интерфейс к разным размерам тела) и продаётся в магазинах, а не индивидуально шьётся в ателье. Если это программное обеспечение, то используется «коробочное», без длительной настройки (или с настройкой LowCode, без задействования программистов, силами «продвинутых пользователей», а сегодня и системы NoCode с естественноязыковым интерфейсом). Индивидуально под заказ сделанные инженерные системы и даже отдельные модули становятся системами для элитного потребления. Этот тренд в существенной мере следствие тренда на стандартизацию интерфейсов. Вариабельности продуктов/продуктовых линеек — это тренд платформизации (базовый модуль и отдельные модули для прикладных сервисов с чётко определёнными для них интерфейсами) с учётом хода на готовые системы (все системы должны выпускаться массово, а не индивидуально). Если присмотреться, то готовая продукция имеет множество вариантов исполнения (тренд платформизации), но эти варианты исполнения не нужно специально заказывать — они уже есть готовые (COTS). Помним, что вариабельность тут ведёт к множеству продуктов с примерно одинаковыми характеристиками, из которых трудно выбрать, и при этом появляются всё новые и новые продукты с примерно похожими характеристиками, которые очень медленно, но улучшаются, а время от времени улучшаются кардинально: это как раз «неустроенность», наличие множества субоптимальных решений с похожими характеристиками, следствие системных конфликтов и многоуровневой оптимизации в ходе меметической/техно эволюции.
-
Продвинутые материалы, которые делают возможными новые инженерные системы. Тут даже не столько такое, как переход в ракетостроении от алюминия к стали в корпусах (основное в ракетах — это большая прочность при высоких температурах, эту прочность сталь на единицу веса даёт выше, чем алюминий, который выгодней по весу только при низких температурах). Но, например, новые лекарства, новые сверхпроводники, мета-материалы18.
-
… Это только примеры трендов, этих трендов много больше.
Конечно, есть тренды не совсем инженерии (хотя вопрос спорный: ведь мы договорились, что «всё — инженерия»). Например, бизнес-модель систем с открытыми исходниками (open source — термин используется и для программного обеспечения, и для электроники, и для всего остального), которая выводит на пересмотр границ того, что и как может быть разработано в рамках одного предприятия. Прибыль при такой бизнес-модели получается не за счёт продажи «интеллектуальной собственности» каких-то систем, а за счёт альтернативных способов заработка: или обслуживания, или использования сторонних разработчиков для собственных нужд, или через использование открытой документации в качестве рекламы основных сервисов. В любом случае, если два десятка лет назад открытые исходники были «исключением из правил», то теперь их использование никого не удивляет.
Чтобы отслеживать такие тренды, нужно следить за текущей литературой. Часть из них связана с распространением системного мышления (стандартизация интерфейсов), часть с лучшим пониманием математики операционной работы (small batch size как основа «аджайлизации»), но значительная часть — с успехами моделирования, в том числе порождающего моделирования (когда речь идёт не только о создании модели, но и создании по модели каких-то предположений о мире. «Порождающее моделирование» — это в какой-то мере «антимоделирование», где на основе модели нужно создать описание мира, а не на основании описания мира создать модель), а часть этих трендов получена «случайно», то есть в ходе техноэволюционного процесса порождения нового, базирующегося на случайных мутациях мемов и естественном отборе удачных мутаций.
Искусственный интеллект на основе нейронных сетей стал известен широкой публике только в 2012 году. Сфера его применения в системной инженерии практически та же самая, что и естественного интеллекта (по факту используется всегда коллективный гибридный интеллект: множество естественных интеллектов, обычных компьютерных программ и баз данных и какие-то варианты искусственного интеллекта, например, алгоритмы на основе глубоких нейронных сетей). Уже сегодня искусственный интеллект на уровне среднего человека стоит дешевле школьника (переводчик Гугла тут как раз пример). Ситуация быстро меняется, и через несколько лет (мнения расходятся, но большинство считают, что через 2-5 лет) можно ожидать появления компьютерного интеллекта, обладающего для широких классов инженерных задач сверхчеловеческой силой (сверхчеловеческой — это «более умных, чем лауреаты Нобелевской премии»). Это существенно изменит все инженерные методы, для всех системноинженерных/эволюционных уровней сложности.
Можно ожидать, что искусственный (а на самом деле гибридный, ибо речь идёт о совместном мышлении людей и машин в коллективных проектах, а ещё искусственный интеллект учится на результатах предыдущих работ естественного интеллекта людей — граница естественного и искусственного тут крайне размыта) интеллект будет использовать те же принципы устройства инженерного проекта, которые описаны в нашем руководстве. Если потребуется обучить искусственный интеллект хорошей инженерии, то мы могли бы ему посоветовать взять это наше руководство, но ещё и обязательно все руководства-пререквизиты.
Моделирование: инженерные тренды и мой рабочий проект
В предыдущем подразделе руководства дан список трендов в инженерии (трендов больше, это только пример). Заполните табличку комментариями, в которых вы даёте название тренда (из нашего руководства или кастомизированное/адаптированное для вашей прикладной предметной области), как вы его интерпретируете в терминах вашей прикладной предметной области (используете типы и термины не мета-мета-модели из нашего руководства, но типы и термины мета-модели предметной области), и комментируете, как он проявляется в вашем проекте (вы его игнорируете, ваш проект на нём основан, вы планируете действия по его отражению в проекте). Добавьте минимум ещё один (но лучше — больше) из инженерных трендов, которые вы наблюдаете и отслеживаете.
| Номер п/п | Название тренда (по нашему руководству, но лучше бы кастомизированное для предметной области рабочего проекта) | Как тренд проявляется в вашем проекте | Что вы планируете в связи с этим предпринять |
|---|---|---|---|
| 1. | |||
| 2. | |||
| 3. | |||
| 4. | |||
| 5. | |||
| 6. | |||
| 7. | |||
| 8. | |||
| 9. | |||
| 10. | |||
Что делают разработчики
В инженерии исторически образовалось довольно много разных пониманий разделения труда. «Инженер» — это некоторая составная общая архироль, появление «системного инженера» не слишком улучшило ситуацию, но ведь есть ещё и разработчик (developer), и проектировщик (designer), и даже «рабочий» — за каждым словом тут множество самых разных значений, плюс ещё и полностью устаревшее различение «инженеров» как «белых воротничков», занятых умственным трудом, а «рабочих» и «техников» как «синих воротничков», занятых физическим трудом. Инженерия эволюционирует, разделение труда меняется, при этом в каждом конкретном проекте можно встретить самые разные варианты, ибо отнюдь не все предприятия следуют современному инженерному процессу с современным разделением труда. Как разбираться с «винегретом» значений? Как всегда: обсуждая развёрнутое описание, а не «определение» (которых легко наберётся сотня-другая противоречивых из разных источников).
Трудности начинаются с самого термина разработка/development::метод, и тем самым в определении того, кто такой разработчик::роль. У слова development довольно много словарных значений, все их можно найти в инженерии:
-
Иногда developer — это не столько «разработчик», сколько неопределённый «развиватель», а development — «развитие». Так, директор по развитию в инженерии предприятия/менеджменте понимается как «ответственный за рост компании» путём экспансии на новые рынки, или просто рост компании путём применения новых технологий/организационного развития. «Девелоперы» в недвижимости/урбанистике, это «развиватели» территории, где потихоньку evolve всё, что нужно для комфортного проживания.
-
Чаще всего development — это «разработка» в широком смысле, метод получения какого-то продукта в его конечном виде, но до момента массового заводского производства в киберфизических системах, размножения в сельском хозяйстве, введения софта в эксплуатацию на рабочих серверах в случае корпоративного софта. Включает в себя в том числе и выявление потребности (в системе или одной фиче системы), и разработку архитектуры (термин легко терпит «разработку в разработке», то есть разработка архитектуры в разработке целевой системы), и проектирование/design, и изготовление/manufacturing, и обеспечение безопасности и защиты (safety and security), и проведение испытаний, и непрерывный ввод в эксплуатацию: всё, кроме собственно эксплуатации.
-
Development как «разработка командой» в узком смысле, проектирование системы и её частей, отделённое от архитектуры (у которой отношение надзора к разработке разными командами), производства (которое предоставляет инфраструктуру непрерывного ввода в эксплуатацию (сontinuous delivery) и связанных с ними сборки, тестирования и мониторинга), и иногда ещё выделяют как отдельные обеспечение безопасности/safety и защиты/security.
Напомним табличку с ролями в разделении труда (системного) инженера:
Вот существенно упрощённая картинка, показывающая взаимоотношения всех этих ролей:
Проектировщик в соответствии с рекомендациями прикладного методолога, ответственного за динамический аспект системы и в соответствии с принятыми архитектором решениями делает проект/design системы и передаёт его технологу, который проводит этот проект/design через изготовление, сборку, обоснование успешности (тестирование), разворачивание и пуск в эксплуатацию. Оператор (он же пользователь) работает во время эксплуатации системы, визионер понимает текущую (или будущую!) ситуацию в эксплуатации и разработке — и планирует очередь реализации новых фич системы, передавая её проектировщику (то есть это не однократный проход по процессу, это непрерывная разработка, continuous development). Отдельно тут инженер внутренней платформы разработки (internal development platform), который готовит инструментальный «конвейер», на котором работают все остальные роли — инструменты методолога, проектировщика, архитектора, технолога, визионера. Конечно, «инженер внутренней платформы разработки» внутри себя рекурсивно содержит все упомянутые роли: в маленькой разработке софта это может быть пара-тройка человек, а вот в ракетостроении — люди, которые строят ракетный завод, да ещё и разворачивают софт моделирования для конструкторского бюро.
Одно из неуказанных различий роли разработчика и ролей визионера, архитектора и инженера платформы разработки в том, что в маленькой разработке это всё роли одной небольшой команды, но в большой разработке роли визионера, архитектора и инженера платформы разработки обычно вынесены на уровень разработки системы в целом (приоритеты разработки тех или иных фич у визионера, раздаваемые командам модули, общий для всех инструментарий разработки), а составляющие роли разработчика появляются на уровне команд, которые разрабатывают отдельные модули.
В нашем руководстве мы выделим отдельно команду разработчиков в узком смысле слова, выполняющих метод разработки (проектирования) в узком смысле слова: не всей системы, в целом, а в рамках отдельной команды. Вот иллюстрация предельно упрощённого разделения труда внутри команды разработчиков:
На картинке намеренно проектировщик отвечает за конструкцию и чёрного ящика (спецификация интерфейсов, учёт компоновки, сама система целиком — это ведь не только функциональный объект в надсистеме, но и конструктив тоже), и для прозрачного ящика (подбор или даже изобретение комплектующих и компоновки такой, чтобы выдавать необходимый набор функций). И прикладной методолог и за внешнюю функциональность, и за внутреннюю отвечает. Совместная работа всех, но всё-таки разделение труда по видам описаний, в которых профессионализируются. Визионер же ничего не разрабатывает, но отвечает за то, чтобы это был бизнес (а если не бизнес, а благотворительность, то было бы понятно, кто добровольно оплачивает эту благотворительность, а не обнаруживает это уже после того, как потрачены ресурсы на никому не нужную разработку).
Вот что делают разработчики внутри команды, причём непрерывно по ходу жизни многих версий системы, а не разово «от замысливания до выпуска» одной версии:
-
Узнают потребности внешних проектных ролей, узнают структуру клиентской предметной области (реверс-инжиниринг надсистемы), то есть делают концепцию использования, модель системы как «чёрного ящика». Никакого испорченного телефона, промежуточных «аналитиков». Результат тут сегодня часто даже не use cases, а юнит-тесты, документирующие ожидаемое поведение системы в части каких-то возможностей/фич/features. Это делает главным образом визионер (часто внешний по отношению к команде, например, это половинка должности product owner или product manager) и проектировщик.
-
Выполняют концептуальное проектирование, то есть делают концепцию системы (включая использование известных им паттернов, поиск в литературе/культуре, и изобретения/творчество). Концепция системы получается на стыке работы прикладного методолога (синтез функций как описания динамики системы, её поведения) и архитектора (синтез конструкции как модулей системы, связанных через интерфейсы). Архитектор, который задаёт границы и интерфейсы проектируемого модуля как чёрного ящика, чаще всего внешний для разработчиков, но внутри модуля в прозрачном ящике тоже нужно проводить архитектурную работу, её чаще всего выполняет проектировщик/designer. А вот прикладной методолог внешний довольно редок (функциональная нарезка на верхнем уровне не очень осмысленна для больших систем, реализациям маленьких фич требует узкоприкладного функционального синтеза), и роль методолога начинает выделяться всё чаще и чаще внутри команды — но названия разные: от process engineer до functional architect. Не надо забывать, что под словами engineer, developer, designer и даже architect могут скрываться самые разные роли, поэтому очень часто тут можно встретить «эпитеты», например, functional architect указывает, что речь идёт не о модульной эволюционной архитектуре, а о функциональном описании (раньше это было частью архитектуры, как «всё важное, что делали разработчики», в том числе и функциональная, и модульная часть), если говорится о process designer, functional designer — это всё тоже прикладной методолог. И даже functional analyst может быть прикладным методологом, при этом игнорируют, что речь идёт не об анализе, а о синтезе функционального описания.
-
Выполняют нарезку работы на маленькие кусочки (задачи/tasks), соблюдая принцип small batch size и другие принципы операционного менеджмента. Это роль менеджера, которая даже не указана.
-
Выполняют работы по инженерным обоснованиям: создание тестов в рамках сдвига влево (shift left, общий принцип переноса того, что делалось раньше в конце жизненного цикла в самое его начало: тестирование, учёт ограничений безопасности и защиты, и т.д.), а затем выполняют тестирование. Могут существовать и отдельные команды тестировщиков, но главная работа по созданию функциональных тестов и тестированию у самих разработчиков — прежде всего у проектировщиков.
-
Выполняют работы по безопасности и защите, принимая внешние ограничения у специалистов (мы считаем, что архитекторы и специалисты по безопасности и защите только по недоразумению не одни и те же, поэтому не показываем отдельно этих специалистов), причём в рамках сдвига влево (то есть не по итогам тестирования готовой системы, а прямо в ходе принятия проектных решений).
-
Выполняют проектирование с точностью, достаточной для изготовления (design for manufacturing). В классической инженерии это non-architectural part of design, в конструировании и проектировании это работа с CAD и далее выход на программы для станков с ЧПУ или 3D-печать, а в программной инженерии это собственно кодирование/coding (хотя в программной инженерии скорее скажут coder, чем designer/проектировщик).
-
Выполняют работы по подготовке производства: выпуск технологической документации, вплоть до программ для станков с ЧПУ, а в программной инженерии до скриптов прогона инкрементов кода через инструментарий компилирования, тестирования, интеграции, разворачивания, пуска в эксплуатацию. Инструментарий готовит инженер внутренней платформы разработки.
Все эти роли перепутаны, команда неформально принимает это разделение ролей, а ещё есть неминуемые недоговорённости от того, что разработка встречается трижды, и можно было бы ожидать трёхкратного воспроизведения ролевой структуры для отдельных ролей, но этого по совокупности причин не происходит:
-
Разработка в целом (так, там есть роль архитектора, визионера, инженера внутренней платформы разработки — которые работают на уровне всей системы), и роль разработчика модуля, который работает на уровне модуля — и считается, что эти разработчиков несколько.
-
По идее, роль разработчика модуля должна бы воспроизвести у себя полный набор всех ролей: визионер модуля, архитектор модуля, разработчик модуля(!) и будем считать, что инженер операционной платформы тут необязателен. Менеджерские роли (прежде всего, операционный менеджер) не рассматриваем. Коллизия тут в том, что откуда-то появляется роль разработчика внутри роли разработчика. И если в модуле появляется ещё более мелкий уровень модуля, то можно ожидать «разработчика внутри разработчика внутри разработчика». Но это игнорируется, и визионер модуля считается внешним, а «архитектор модуля» совмещается с проектировщиком, который «задаёт конструкцию» (в том числе архитектурные решения для модуля и выбор аффордансов-конструктивов).
-
Инженер внутренней платформы разработки строит эту самую платформу — и для этого внутри себя должен иметь полный набор инженерных ролей, по сути это «проект в проекте» (а часто это «проект вне проекта»: завод и конструкторское бюро уже построены, ими надо только пользоваться). Но мы тут не будем делать разворачивания полного инженерного процесса для «строительства конвейера», «инженерии инструментария выпуска системы», «создания тёмной холодной фабрики» (у этой культуры много имён, совсем недавно тут были в ходу ещё и такие имена, как DevOps и SRE, в инженерии предприятий тут администрация, в инженерии мастерства тут деканат).
Основное, чем пользуются разработчики (напомним, что мы очень грубо разложили их роль на составляющие методолога, проектировщика, технолога, оператора) в своей практике — это самые разные моделеры. В методах поддержки DDD (domain driven design, помним, что design как раз «проектирование», выполняется проектировщиком, а в части функционального проектирования — методологом) типа EventStorm (мы расскажем об этом методе подробней чуть позже) моделером выступает стена и липкие листочки разного цвета с надписями фломастером. Но это, конечно, исключение. Главным образом используются специализированные моделеры (IDE, CAD — сегодня обязательно с AI-copilot и AI-agent для vibe coding в программной инженерии и vibe design в «железной» инженерии), ибо вся разработка идёт сегодня как model-driven (синоним: model-based): делается цепочка всё более и более детальных и точных моделей, которые потом используются для автоматического (не руками! Внутренняя платформа разработки — это прежде всего средства автоматизации выпуска: изготовления, интеграции, обоснования/испытания, разворачивания, ввода в эксплуатацию, мониторинга работоспособности) выпуска/delivering целевой системы.
В старинной разработке момент перехода от модели::описание (чертежи, исходный код) к части системы («в железе», «в бетоне», «в облаке») был важным гейтом, принималось решение о том, будут ли вкладываться материальные ресурсы в проект. Затем это перестало быть хоть какой-то особой операцией: модели вышли на некоторую критическую для успеха изготовления точность и полноту описания, а изготовление вышло на некоторую критическую для последующей сборки точность изготовления. Риски по результатам моделирования в ходе разработки получить какую-то деталь, которая будет неудачна, существенно упали.
Интеграция/integration как объединение изготовленных частей в целую работоспособную систему требовала творческой работы. Скажем, при разработке самолёта прилаживание двери сложной формы к фюзеляжу могло на заводе занимать пару недель. А теперь это «прикрутить три болта». То же самое с домашней мебелью: собрать какую-нибудь кровать дома могло требовать немаленькой инженерной подготовки, ибо дырки для болтов при совмещении деталей банально не совпадали друг с другом. Нужно было «дорабатывать по месту напильником». Если один разработчик проектировал стены, а другой проектировал водопроводную сеть, то в стенах проходы для труб могли быть и не запроектированы, их надо было пробивать «на месте», в ходе строительства. Если это было на подводной лодке, то все прочностные расчёты и решение проблем герметизации отсеков надо было переделывать. Сейчас такого быть не может: многоуровневое моделирование выявит проблему раньше, точное изготовление сделает так, что «в модели» и «в жизни» будет совпадать, тестирование обеспечит проверку как намоделированного, так и изготовленного, а управление конфигурацией заранее выявит все возможные коллизии — чаще всего ещё в проекте, до изготовления.
Конечно, все эти проблемы решались не только за счёт того, что всевозможные моделеры стали лучше, а изготовление деталей стало точнее, поэтому сборка тоже получалась беспроблемной. Собрать беспроблемно ведь можно и что-то ненужное! Это решилось тем, что разработчики избавились от «испорченного телефона», стали общаться со специалистами предметной области надсистемы непосредственно, а не через «аналитиков», «инженеров по требованиям» и прочих посредников. Моделированием окружения тоже занялись разработчики, «с чужими анализами в нашу больницу не берут». Тесты тоже разрабатывают сами проектировщики, слухи про «внешние независимо разработанные тесты более качественны» оказались неподтверждёнными исследованиями. То, что «независимые тестировщики» выдают процент найденных ошибок примерно такой же, что и сами проектировщики — это контринтуитивно. Конечное слово всё равно остаётся за использованием системы, а не изготовлением (система может очень плохо работать, хотя пройти все запланированные испытания). Так что нужно просто уметь быстро-быстро всё переделать по обратной связи от пользователей, чтобы избавиться от ошибок — ошибок по мнению пользователей, а не ошибок по мнению проектировщиков. Это мы обсуждали как customer eXperience (для успеха системы прежде всего важны впечатления пользователей системы, а не впечатления разработчиков).
Для итоговой безошибочности/бездефектности оказалось важнее обеспечить скорость перемоделирования в части исправления ошибки и затем повторного изготовления и сборки, а не бесконечное тестирование системы по жёстко задокументированным спецификациям. Важней оказалось соответствие ожиданиям пользователей во время эксплуатации, а не соответствие спецификациям во время разработки и обоснований. Вот этот переход к учёту customer eXperience крайне важен в современной разработке:
-
Скачок в «голову пользователя», проверка «за пользователя» — что жмёт и плохо в системе для пользователя, а не для разработчика.
-
Скачок из времени разработки во время эксплуатации — систему надо смотреть работающую, а не изготавливаемую.
Это мышление с вниманием к customer eXperience разработчикам освоить очень трудно, для этого нужны тренировки.
Переход к «отладке системы для безошибочности в глазах пользователя» очень контринтуитивен. Этому сопротивляются главным образом менеджеры, которые не очень разобрались в том, как устроена реальная инженерная работа: им удобнее отчитаться не за работоспособность системы в ходе эксплуатации в быстроизменяющейся жизни у пользователя, а удобнее отчитаться за разовое подтверждение выполнения стабильных «требований» момента разработки, а что там в эксплуатации с customer eXperience — это будет решать какой-нибудь другой менеджер, но не менеджер разработчиков.
А ещё собрать беспроблемно можно какую-то группу деталей в подсборку, а потом получить огромные проблемы на сборке уже из подсборок. Тут помогает непрерывная интеграция (continuous integration), которая подразумевает непрерывную сборку целостной версии моделей системы с проверкой конфигурационных коллизий. В этой практике идёт нарезка работ по разработке системы на маленькие части:
-
Части, определяемые ограниченным контекстом/bounded context, то есть одной предметной областью в проекте, моделирование-проектирование/design которой поддерживается одной командой. Аккуратное разбиение на части — это результат архитектурной работы архитектора целевой системы (нарезка системы на части верхнего уровня и определение интерфейсов их взаимодействия) и архитектора предприятия, нарезающего предприятие на команды разработчиков.
-
Части, определяемые инкрементальностью разработки: начиная с минимальности системы, которая выдаёт минимальный набор функций, позволяющий её использовать хоть как-то (MVP, minimum viable product: «молоток, но пока без ручки, и даже дырки для ручки нет», но не «ручка, пока без молотка на ней»), а потом увеличивающийся очень маленькими инкрементами набор «фич» целевой системы. Инкременты берём сегодня даже не на день работы команды, а на часы — а не на неделю или месяц (small batch size, частота релизов важнее собранной в этих релизах функциональности: гонимся не за выпуском большого числа новых фич в одном релизе, а за непрерывностью разработки — в пределе будет по одной фиче в релизе, релизы часты, непрерывны, continuous delivering).
После проектирования (в том числе проектирования с точностью, достаточной для изготовления — design в «железной инженерии», кодирование в программной инженерии) каждая команда выдаёт поток небольших инкрементальных изменений в общую «магистраль» (trunk) сборки, и это происходит ежедневно (иногда ежечасно), но не еженедельно и уж тем более не ежемесячно. Это метод магистральной разработки (trunk-based development19) вместо метода «долгоживущих ветвей для изменений» (long-lived feature branches) и последующих больших шагов по интеграции. Сегодня это уже метод не только программной инженерии, но и «железной» инженерии: в самолётостроении конструкторы результаты своей работы выкладывают в общую PLM-систему немедленно, каждый день, а не по мере окончательной готовности каких-то крупных частей. Ещё лет десять назад в моде была поговорка, что «дураку половину работы не показывают», сегодня на эту поговорку сразу возражают:
-
Смотрят не дураки, поэтому с такими заявлениями нужно быть осторожней.
-
Значит взял слишком большую работу, надо было поделить её на части, которые можно показывать.
-
Если не показываешь, то ошибки (начиная с того, что вообще ненужную работу делаешь, не тем занялся) выявятся позже, а это недопустимо.
-
Покажи ещё и тесты для своей работы.
Каждая интеграция маленького инкремента не занимает много времени, а если выявляются «большие проблемы» (например, необходимость доработки интерфейсов), то они выявляются рано. То, что это небольшие законченные части, помогает как с обеспечением «потока» (flow) работ в части менеджмента (отсутствуют «заторы» в местах ограничения/constraints потока — small batch size метод), так и помогает быстро находить ошибки, уменьшать число переделок/reworks в части прикладной инженерной работы.
Команды быстро получают обратную связь от эксплуатации и немедленно на неё реагируют (если число дефектов превышает какой-то предел, то новыми фичами прекращают заниматься, а только исправляют ошибки — это основа метода SRE, site reliability engineering20, применяемого инженерами внутренней платформы разработки и реализуемого инженерами-технологами), метод vulnerability management даёт понимание сроков исправления найденных при эксплуатации уязвимостей в зависимости от уровня их серьёзности, а метод FinOps21 передаёт ответственность за стоимость эксплуатации в команду разработки в случае использования облачной инфраструктуры (а если инфраструктура собственная, а не облачная — можно использовать, например, chargeback22).
Это всё, конечно, поддерживается довольно развитой организационной и инструментальной инфраструктурой, которая поддерживает работу команды. Сама по себе команда разработчиков не сможет работать, чудес не бывает.
Итого: команды работают максимально независимо друг от друга маленькими улучшениями/инкрементами в релизах, поддерживая тесную связь с исполнителями внешних проектных ролей в надсистеме (часто на много уровней вверх), находясь под архитектурным надзором (и очень похожим надзором по линии безопасности и защиты), а также опираясь на внутреннюю платформу разработки (инфраструктуру), которую предоставляют инженеры этой платформы (платформа будет давать сервисы управления конфигурацией, тестирования и другой инфраструктуры, нужной для непрерывной интеграции/continuous integration и затем непрерывного введения в эксплуатацию). Разработка немыслима без взаимодействия с внешними проектными ролями в эксплуатации, архитекторами, инженерами внутренней платформы разработки (она же — инфраструктура изготовления, она же — производство) и менеджерами.
Мы переводим continuous delivery не просто как выпуск (release), ибо выпуск обычно у разработчиков («выпуск новой версии»), не «поставка» (это логистическая операция) и даже не «разворачивание» (deployment, установка на месте), но конечной операцией попадания в руки потребителя/пользователя после всех предварительных операций доставки на место, установки на место и настройки: ввод в эксплуатацию. В «железной» инженерии это transfer, commissioning. «Ввод в эксплуатацию» наиболее точно отражает смысл понятия continuous delivering и даёт возможность использовать его для систем самой разной природы. Ввести в эксплуатацию банан — это не доставить его домой в полиэтиленовом пакетике, не освободить от упаковки, не почистить от кожуры. Ввести в эксплуатацию банан — это выдать его готовым для еды, чтобы можно было сразу откусить, без дополнительных очисток-распаковок-готовки. Если вы получаете банан, готовый к откусыванию и каждый раз чуть более вкусный раз в час (или хотя бы раз в день, но никак не раз в неделю или месяц), то поздравляем — у вас continuous delivery, это важнейший метод эволюционной/непрерывной инженерии. Эта эволюционная/непрерывная инженерия начинается с того, что кто-то придумал вырастить и продать вам банан, кто-то его таки начал выращивать и менять сорта на более вкусные, а затем непрерывно собирать урожай спелых и всё более вкусных бананов, поставлять их вам и готовить к еде без дополнительных подготовительных ваших операций — это и будет continuous development, а затем уж это continuous delivery. Банан тут плохой пример, ибо он будет просто каждый раз тот же самый, а смысл затеи в том, что доставляемый-очищаемый-проверяемый для вас каждый час новый банан будет лучше старого, или хотя бы «такой же вкусный» при изменении ваших вкусов (это тоже надо учитывать! Прежний вариант банана будет тогда вкусный для вас-прежнего, но не для вас-нынешнего!): при непрерывной инженерии банан будет эволюционировать под ваши постоянно изменяющиеся вкусы и постоянно будет готовым к тому, чтобы вы с удовольствием его съели без дополнительных операций готовки, в этом весь смысл затеи continuous delivery!
При этом всё это в реальности устроено ещё сложней, ибо для вас на всякий случай не только очищается, а потом «ради роста культуры еды» нарезается банан, но и одновременно ещё пару десятков фруктов, а ещё первые-вторые блюда и салаты, и вообще непрерывно и круглосуточно работает шведский стол со всем его разнообразием продуктов, где всё магическим образом поддерживается свежим, вкусным с учётом изменений вкуса, надёжным и безопасным, доступным и никогда не кончающимся даже ночью — но начинает всё содержимое этого шведского стола свою жизнь на самых разных полях и фермах и проходит довольно большой путь переработки и логистики. Современная разработка софта корпоративных информационных систем представляет собой примерно вот такое поддержание «шведского стола» программных сервисов, доступных сотрудникам. И то же самое потихоньку начинает происходить с любой другой инженерией: чем бы ни занялись, в конечном итоге в идеале получится поддержка того же «шведского стола», да ещё и с доставкой на дом. Даже образование — это поддержка такого же постоянно действующего «шведского стола» мастерства, а не организация разового обеда. Может, метафора эта и немного натянута, но она очень полезна — режим поддержки «шведского стола» существенно отличается от режима приготовления одного обеда.
В инженерии киберфизических систем огромное влияние оказывает также переход к так называемым software-defined технологиям, где традиционно «аналоговые» части системы попадают под контроль какого-то встроенного/embedded софта/software (напомню, что мы предлагаем и в письменной речи кратко писать «софт», хотя иногда и пишем канцеляритное «программное обеспечение» или даже соответствующее каким-то стандартам «программные средства»).
Если алгоритм работы устройства (атомной станции, фотоаппарата, автомобиля, смартфона) определяется софтом, то вы можете смело использовать все принципы разработки софта, и далее менять этот софт хоть каждый день. Так, функции помощи водителю в автомобилях Tesla определяются программно и регулярно обновляются, но само «железо» автомобиля при этом остаётся неизменным. Это общеинженерный тренд: доработки целевых систем ведутся всё время, включая время после введения этих систем в эксплуатацию. То есть continuous delivery (непрерывный ввод в эксплуатацию со всё новыми и новыми фичами, всё новыми и новыми исправленными ошибками, а иногда и со всё новой и новой архитектурой, которая позволяет далее менять систему более быстро) используется и в «железной» инженерии. И уж тем более в инженерии предприятия, где и команды, и предприятие в целом ежедневно изменяются в части своей организации и методов своей работы, а не застывают после разового изготовления, сборки, наладки и «пуска в эксплуатацию».
Сдвиг влево (left shift) — это общее название для тренда, который двигает работы по практикам, расположенным далеко справа на функциональной/логической V-диаграмме, в самое начало логического времени разработки. Скажем, тестированием традиционно занимаются в конце проекта разработки, когда всё уже сделано. Но testing left shift (с этого и началось всё движение сдвига влево) означает, что сама разработка начинается с предложения тестов. Если ты понимаешь, что ты делаешь, то ты можешь это проверить: вот и напиши тесты, покажи понимание задачи. А потом разработай систему, которая эти тесты пройдёт. Описание тестов сначала, разработка потом, затем тестирование, доработка, развитие тестов, ещё доработка, тестирование, развитие тестов и т.д. Но описывать тесты нужно до начала разработки (сразу тесты как документирование гипотез того, что должна делать система — тесты как функциональное описание чёрного ящика).
Безопасность/safety? Сразу подумайте, а не после того, как к вам придёт инспекция или что-то плохое произойдёт из-за вашей системы в жизни. Защита/security? Сразу подумайте, будьте прочным23! Не берите архитектуры, которые легко взламываются, не берите в проект готовые (COTS) части системы, про уязвимость которых вам ничего не известно! Учитывайте защиту сразу, а не после того, как вашу систему взломали!
То же самое происходит буквально со всем остальным, что оставлялось «на потом». Сначала спроектируем, потом будем думать о том, как изготовить? Нет, думайте сразу, и то же самое про изготовление и многое другое. Это обобщается иногда как тренд «design for X»24 или «design for eXcellence» (DFX): design for manufacturing, design for cost, design for power в электронике, design for inspection и т.д., включая даже просто понимание множественности целей проектирования как design for eXcellence в подходе Six Sigma как одном из вариантов Lean методологии. Смысл сдвига влево в том, что предметы интереса, неизбежно возникающие «потом», рассматриваются «сначала», то есть учитываются разработчиками сразу. Это кажется невозможным (слишком много чего нужно учесть), но каким-то образом в современных проектах получается. Впрочем, это не «каким-то образом», а вполне понятным образом, который как раз и обсуждается у нас в руководстве: команда разработчиков хорошо «вооружена» и использует множество поддержанных компьютерами методов работы, которых некоторое время назад на планете попросту не существовало, а объяснительные теории для этих методов были массово неизвестны. И это очень контринтуитивные методы, их использованию разработчиков нужно учить специально, без обучения и объяснения они в проекте невозможны.
Успех в разработке достигается за счёт развитого порождающего моделирования (руками никто не рисует, всё больше и больше работы перекладываются на компьютер, разработчик по факту только формулирует задание моделеру), разработка хорошо документируется, поэтому «все ходы записаны», а не «проект у меня в уме» и «я ему неделю назад устно сказал». Управление конфигурацией тоже даёт свой вклад в успех разработки (все коллизии между «записанными ходами» обнаруживаются рано). Успех непрерывной разработки достигается за счёт хорошей модульности вследствие тщательной проработки архитектуры (ошибки не распространяются далеко по системным связям и остаются внутри модуля, один неудачный модуль не останавливает всю систему, неработающая «фича» — это не неработа всей системы в целом, архитектурные характеристики имеют метрики и отслеживаются, независимые модули могут разрабатываться независимыми командами). Разработка следует SoTA в определении того, как будет работать система — учёт прикладной методологии предметной области, велосипеды не изобретаются, но для достижения функциональных и ценовых характеристик лучше, чем у конкурентов наоборот — изобретения приветствуются.
Разработка происходит инкрементально с очень маленькими и быстро проводимыми изменениями (continuous delivery). И главное: разработка эволюционна/непрерывна (continuous development) и гибка (agile). Она никогда не заканчивается и не идёт по строгим этапам, а учитывает:
-
всё новые и новые обнаруженные в проекте особенности окружения (оно меняется постоянно, это жизнь!),
-
проблемы в работе разрабатываемой (под)системы (ошибки находятся постоянно!),
-
особенности непрерывно меняющихся моделеров (их AI-возможности меняются очень быстро)
-
организации разработки (они тоже непрерывно меняются — и даже, когда изменения к лучшему, а не «энтропия разрушит и нас», к этим изменениям нужно адаптироваться).
Успех системы оказывается не «достигнут», а «непрерывно достигаем» — успеха надо не просто достичь, надо его долго удерживать, современная эволюционная разработка с её «непрерывным всем» нацелена именно на это, достижение ускользающего успеха, а потом долгое его удержание.
Смерть инженерии требований
Когда первые версии нашего руководства писались до примерно 2017 года, то в нём был раздел по методам инженерии требований как обязательной составляющей лучших методов системной инженерии. Работой по этому методу занимался инженер по требованиям, одна из специализаций роли системного инженера.
Но всё изменилось, когда с 2017 года в литературе по программной инженерии вдруг перестали появляться новые книги по инженерии требований, а в 2022 году и в «железной инженерии» такие книги стали редкостью. Развитие инженерии требований прекратилось, а в работах по инженерии исчезли подробные описания методов инженерии требований, хотя само понятие требований иногда и упоминается, если речь идёт о самых консервативных областях инженерии. Наше руководство учло этот тренд, в текущих его наставлениях не говорится о требованиях, инженерии требований, роли инженера по требованиям.
Это очень контринтуитивно: если система не описана как чёрный ящик в деонтической модальности (это и есть «требования»), то как архитектор и разработчик узнают, какую систему нужно делать? Как испытывать систему, если нет требований? Увы, это всё вопросы, которые осмысленны в уходящем веке «водопадной системной инженерии», где каждая роль выполняет по очереди свой метод и передаёт результат дальше по цепочке как обязательный для следования, в том числе передаёт разработанные в проекте требования (такого, чтобы требования были разработаны клиентом, обычно нет — требования разрабатывал инженер, а клиент лишь соглашался с разработанным).
В книге «Learning Domain-Driven Design. Aligning Software Architecture and Business strategy», 2021, Vlad Khononov рассказывает, что традиционный ход разработки корпоративного программного обеспечения (часто называемого «кровавый энтерпрайз» в среде программистов) представляется как перевод разными людьми какого-то знания об организации на свой собственный профессиональный язык (скажем, «счёт» у продавца становится «офертой» у юриста, «структурой данных» у программиста).
Эти представления переводятся людьми в какие-то тексты или информационные модели, а затем идёт передача текстов и моделей на этих профессиональных языках дальше по цепочке из других ролей. Это «испорченный телефон» (Chinese whispers, broken phone), детская игра, где не очень разборчиво все говорят какую-то фразу друг другу на ухо по цепочке, а на выходе получается что-то совсем невнятное и уж точно не то, что говорилось на ухо первому человеку. Вариант этой игры — попытки передать какие-то стихи через цепочку из двух-трёх переводчиков на разные языки. Когда итог переводится на язык оригинала, текст уже невозможно узнать.
Вот эта цепочка, как она существовала раньше в инженерии (и это было много лучше ситуации, когда вообще ничего этого не происходило, а система делалась без внимания к тому, что там происходит в предметной области, «без требований», по наитию разработчиков):
-
Какое-то знание предметной области организации высказывалось специалистами предметной области (subject matter experts), а затем часть этого знания переводилась в «аналитическую модель» аналитиками
-
Аналитическая модель затем переформулировалась в виде «требований», этим занимались инженеры по требованиям. Аналитики не меняют мир, инженеры — меняют. Поэтому аналитики только «делали предложения по требованиям», а инженеры — требовали!
-
Требования становились проектом/design программной системы, этим занимались архитекторы, понимаемые как «опытные разработчики», или даже сразу «опытные разработчики» (в Software Engineering Body of Knowledge архитекторы появились только в 2024 году, в четвёртой версии25), и там плохо различима собственно архитектура как структура системы и методологическая проработка функционального описания, организация системы
-
Проект/design системы становился исходным кодом, этим занимались кодировщики
-
Исходный код становится изготовленной системой, этим занимались DevOps.
И это мы ещё не коснулись тестов, учебных материалов для пользователей и работы служб поддержки пользователей, не коснулись многих других рабочих продуктов.
Описанная цепочка работала плохо (а кое-где она до сих пор работает, и тоже работает плохо), ибо каждое звено цепочки говорило на своём профессиональном языке.
Нам нужно сделать так, чтобы разговор пользователей, разработчиков, операторов системы шёл по возможности на одном языке — языке предметной области. Если речь идёт о финансах, то это язык не инженерии программного обеспечения, а язык финансов. Если это софт, помогающий маркетингу, то это язык маркетинга, но не язык программистов. Никаких «серверов», «асинхронных передач сообщений», «баз данных» в обсуждениях софта! Впрочем, то же самое верно и для любой другой инженерии: обсуждаем постановку задачи для инженеров на языке предметной области пользователей, а не языке разработчиков. Если у вас «органическая основа для электролита» (момент эксплуатации!), то это не «растворитель» (момент, когда разработчик выбирает, что потом станет органической основой для электролита). Если кишечнорастворимая оболочка лекарства (чтобы безопасно донести лекарство до кишечника, а не только до желудка), то не «желатин с добавками» или «агар с добавками»26. Обсуждается то, что должна делать система (какие объекты проявляют какое поведение), а как именно она это делает и из чего состоит, и что там за инструменты, и из чего они состоят — это совсем другие вопросы, их можно решить позже или раньше, и даже не в присутствии представителей внешних проектных ролей.
Поэтому первый аргумент против требований — разработчики не слышат того, что говорят внешние проектные роли, «испорченный телефон» до них это не доносит, в ответ на этот аргумент надо убрать цепочку из людей, а заодно и используемые этой цепочкой «требования» как лишний артефакт. Экономия времени на беседах разработчиков с внешними проектными ролями — мнимая, исправление ошибок понимания через цепочку «испорченного телефона» потом всё равно займёт у разработчика больше времени, плюс ещё потратит время много других людей. Посредников между разработчиками и внешними проектными ролями — выкидываем, а заодно выкидываем и их рабочие продукты, в том числе «требования». У разработчиков будут свои способы записать то, что они услышали от внешних проектных ролей (забегая вперёд: они сразу будут записывать услышанное в виде тестов, а тесты будут сформулированы в терминах предметной области, при этом сама программа или «железо» будет поддерживать термины предметной области. В программе «счёт» будет не «структура данных», а «счёт», в «железе» будет «ограничитель хода заготовки», а не «штырь»).
Второй аргумент в том, что деонтический характер требований (то есть характер долженствования, дозволения, предписания, рекомендации) как-то не очень вяжется с коллективным характером мышления в разработке. Любая разработка сегодня понимается как часть эволюции, часть познания, часть изучения того, как уменьшить неприятные сюрпризы. И деонтическое «я начальник, ты дурак» (с ответом «ты поручил дурацкое, я тебе сделал дурацкое») тут не очень правильно. Поэтому вместо деонтической модальности (долженствования) переводим разработчиков на работу в доксической модальности (веры), вместо приказов выдаём гипотезы, которые надо проверять.
В мышлении инженеров мы используем «научный метод», который оказывается общим и для науки/исследований, и для инженерии. Только в науке мы делаем гипотезы о том, каковы могут быть лучшие объяснения, а в инженерии мы делаем гипотезы о том, какова может быть успешная система, которая меняет жизнь к лучшему. Какие-то идеи могут быть удачны, какие-то нет. То есть не «корпус системы должен быть не более 10 сантиметров шириной, исполняйте», а «сейчас верю, что корпус системы не более 10 сантиметров шириной будет успешен, пробуйте, а если нет, то попробуем другие цифры или вообще сделаем бескорпусное изделие». А где гарантии, что гипотезы подтвердятся? Гарантий нет! Выдвигавший гипотезу может ошибаться, или гипотеза верна для одного момента времени и одной ситуации, но не для другого момента времени и другой ситуации.
В ответ на предложенную гипотезу можно ещё проверить варианты, реализовать не один вариант системы, а несколько разных — и выбрать лучший. В ответ на требования — только выполнить заданное требованием, кто выдал требования — тот принимает на себя ответственность за результат.
В ходе разработки выдвигаем идеи-гипотезы, затем критикуем эти идеи, выбираем лучшие из худших (это особо оговаривается: всегда выбираем не лучший вариант, а наименее плохой, «лучший вариант» не существует в принципе) и реализуем их, проверяя уже жизнью. Потом пробуем улучшить эти идеи, а если не получается улучшить, отказываемся от этих идей и пробуем что-то ещё. С требованиями так не получается, там «делай, что говорят» — критика не уместна, водопад назад не течёт.
В варианте с гипотезами нет требований, но есть какие-то идеи о том, какой могла бы быть система, меняющая жизнь к лучшему (ну, или хотя бы новое поведение/функция системы, функциональный объект, его выполняющий, называют feature), и эти гипотезы сразу можно записывать в виде тестов, которые проверяют их реализацию.
В организационном менеджменте такие идеи сразу называют «предпринимательская гипотеза» (если речь идёт о выпуске нового продукта или новой «фичи» в продукте). В классической инженерии такие идеи имеют специальную форму и их могут называть «концепция», чтобы отличить от жёстких требований. Для системы в целом это могут называть пользовательская концепция (operations concept, OpsCon) или концепция использования (concept of operations, ConOps), причём разные школы инженерии или находят нюансы в различении этих понятий, или наоборот, считают одним и тем же. Мы будем следовать предложениям книги «Systems Architecture. Strategy and Product Development for Complex Systems», 2015, и говорить о просто концепции/concept использования, без нюансов различения (при этом книга выпущена давно, требования, конечно, в ней есть — но есть и концепции).
Эта книжка уже не про программную архитектуру, а системную (прежде всего киберфизических систем, типа ледовой буровой платформы или космического корабля) архитектуру, но в подзаголовок и в книге по DDD, и в книге Systems Architecture вынесена «стратегия»: метод, который должен привести к успеху.
В принципе, и «стратегию» (метод/функция, который по возможности рационально выбирается в ситуации, когда непонятно что делать) можно было бы считать функциональными требованиями к предприятию, но этого слова «требования» в случае предприятия тем более избегают: стратегия сегодня считается непрерывно уточняемой, это тоже гипотеза о том, что было бы в текущей ситуации делать лучше всего (или как заметят архитекторы — что в текущее ситуации делать менее плохо, чем всё остальное, включая делать «ничего»).
В помянутых двух книгах ещё и слово «архитектурный» устарело: до 2017 примерно года архитектурой повсеместно называли решения опытных разработчиков, которые принимались рано по жизненному циклу в силу того, что дальше эти решения было трудно менять без того, чтобы не переделывать всю систему. И эти решения принимались очень похоже на то, как принимались требования — в деонтической модальности, это точно не были гипотезы, разве что требования разрабатывали в инженерной команде, но принимались они вроде как от лица клиентов, а архитектурные решения разрабатывались тоже в инженерной команде, но принимались они от лица опытных разработчиков, называемых «архитекторы». Более того, не слишком различались описания чёрного ящика (система и её поведение, наблюдаемое извне, без описания внутреннего устройства системы и внутреннего поведения системы — требования) и описания белого/прозрачного ящика (система и её поведение, наблюдаемые внутри системы, на уровне подсистем — архитектура как важнейшие решения). В технических заданиях легко можно было встретить в разделе требования и указания на функции системы, и указания на какие-то подробности конструкции (вроде «несущую ось делать из титанового сплава»), и это утверждалось клиентом как «требования», хотя иногда архитектурные решения выдавались за «ограничения» (формально оставаясь, тем не менее, «требованиями», да ещё и «требованиями клиента», хотя разрабатывалось это инженерной командой проекта, а клиент лишь соглашался с результатами этой разработки, «согласовывал»).
Сегодня понятие «архитектуры» как решений опытных разработчиков в части основных решений по верхнеуровневой структуре и организации системы, которые трудно поменять без переделки всей системы — устарело. «Архитектура» теперь относится не «ко всему важному, чтобы это ни было», но только к архитектурным характеристикам и структурным/конструктивным решениям модульного синтеза, о чём будет подробней в следующих разделах.
«Стратегия» тоже перестала быть аналогом важных требований к поведению создателей (в деонтической модальности), но стала гипотезой/догадкой о наименее плохом поведении создателя (доксическая модальность). Стратегия тут — эвристика, суеверие, может и должна пересматриваться.
Требования выполняют, гипотезы и эвристики — проверяют/пробуют. Реализация стратегии — это не выполнение требования, ведущее к гарантированному результату. Это следование эвристике, проба действовать на основе (возможно, ошибочной) предпринимательской гипотезы/hypothesis/ставки/bet, ведущая к возможному, но не гарантированному успеху.
Это означает, что стратегия в случае обнаружения несоответствия гипотезы и жизни может быть подправлена, чтобы это соответствие случилось. И точно: несмотря на то, что книжка Systems Architecture описывает вроде как «водопад», много внимания в ней уделяется идее постепенного уточнения системной архитектуры в её старом понимании (мы будем называть её «концепция системы», чтобы не путаться) в ходе работы над проектом, выдвижение новых гипотез и их уточнение, а иногда всё-таки отбрасывание и переход к полностью новым гипотезам.
Концепция системы («старая архитектура») — это описание того, каким образом какой-то набор конструктивных частей целевой системы исполняет роли функциональных частей системы, чтобы в конечном итоге выдать требуемый от системы сервис на уровень надсистемы в момент использования. В концепции системы выделяют тем самым:
-
Высокоуровневое (на один-два уровня) функциональное описание. Раньше говорили «функциональная архитектура», «логическая архитектура», «функциональная организация», подчёркивалось, что они получаются разбиением сверху вниз. Сегодня — идея «последовательного разбиения сверху вниз в ходе разработки» признана полностью неработоспособной, «так бывает только в сказках». Сегодня чаще всего говорят про из средних слоёв синтез вверх и разбиение вниз при общем итеративном характере процесса. И сегодня вместо разбиения/анализа говорят про синтез функционального описания. Делает этот синтез прикладной методолог, процессный инженер, функциональный проектировщик — названия роли тут могут быть самые разные, на выходе что-то типа «принципиальной схемы» (вы должны быть уже хорошо с этим знакомы, ибо владеете мастерством методологической работы по нашему руководству, в руководстве по методологии об этом было подробно).
-
Высокоуровневое (на один-два уровня) конструктивное описание. Раньше говорили «структура системы», «конструкция», «физическая архитектура». Сегодня говорят просто «архитектура системы», что может легко сбить с толку (раньше архитектура системы по факту была «концепцией системы»). Архитектурное описание говорит о такой архитектуре как разбивке на модули (или не о разбивке, а о синтезе из модулей, «модульном синтезе» — зависит от того, как вы смотрите на конструктивную иерархию), которая даёт необходимые важнейшие архитектурные характеристики (раньше это были «требования качества», которые относились ко всей системе в целом и не относились к предметной области, в которой работала система — не были «функциональными требованиями», определяющими прикладную специфику системы): высокую скорость развития/evolvability для времени создания системы, возможность масштабирования как увеличения производительности по мере роста потребности в сервисе системы, собственно самой производительности системы, и т.д. Конструктивное описание, описание структуры системы — это разбиение на конструктивные модули и определение способов связи этих модулей через интерфейсы. «В сказке» тут тоже сначала надо было разбивать (системный анализ, «разбиение») систему как функциональный физический объект на подсистемы, которые разбивались на всё более и более мелкие подсистемы, а затем конструктор определял самые мелкие детали (деталь — это часть конструкции, которая сама уже не собирается из других частей), которые выполняли функции подсистем (необязательно 1:1, это рассказывалось в руководстве по системному мышлению на примере ножниц и чайника), а проектировщик собирал/синтезировал из этих деталей целую систему как конструктивный физический объект. Идея «только синтез, только снизу вверх» уже признана сказочной, в жизни это невозможно, возможен только итеративный процесс разработки конструкции, тоже чаще всего от средних слоёв конструктивной иерархии постепенно модульный синтез вверх и модульное разбиение вниз, принцип «изнутри наружу». Этим занимается обычно архитектор в его современном понимании, на выходе это чаще всего называется «эволюционная архитектура», чтобы показать её неокончательный и меняющийся характер, и главная там идея — подобрать такие элементы конструкции, чтобы изменение функциональных частей системы по минимуму влияло на изменения конструктивных частей системы. Это мы подробно расскажем в разделе «Эволюционная архитектура» нашего руководства.
-
Кроме согласованных между собой высокоуровневых функционального и конструктивного описания в концепции системы, конечно, участвуют и другие виды основных системных описаний, минимально там ещё описания размещения и стоимостные, но могут быть и необходимые другие описания (это подробно разбиралось в руководстве по системному мышлению).
Концепция использования — это аналогичное концепции системы описание
надсистемы: каким образом целевая система играет в надсистеме функциональную роль, позволяющую достичь нужных функциональных и архитектурных характеристик надсистемы, то есть удовлетворить потребности внешних проектных ролей, а также описание системы как конструктивной части, которая имеет какие-то интерфейсы к конструктивным частям надсистемы, а также эта целевая система где-то размещена и имеет какую-то стоимость.
В упомянутой книге по системной архитектуре очень верхнеуровневая начальная концепция системы называется просто «основная идея», а вот то, что там называется «архитектурное описание» (и даже просто «архитектура», в руководстве по системному мышлению мы говорили, что инженеры очень вольно обращаются с типами и часто используют троп27 метонимии28) даётся по старинке, как дополнение и расширение концепции в сторону прозрачного ящика со всеми видами системных описаний. Конечно, система описывается в том числе и как достигающая каких-то значений важных архитектурных характеристик/-ilities/-остей (например, надёжность, ремонтопригодность, и из относительно новых важных характеристик — evolvability, изменяемость в ходе развития, testability, возможность лёгкого тестирования, deployability, возможность быстрого разворачивания для эксплуатации без длительного нерабочего времени). Архитектурные решения по книге просто детализируют концепцию системы, учитывая множество дополнительных соображений кроме «вот эти функции можно реализовать вот такой конструкцией, чтобы добиться вот таких сервисных характеристик системы-модуля в целом». В современном подходе эволюционной архитектуры принимаемые архитектором решения не столько детализируют все (функциональные и конструктивные) решения концепции, сколько накладывают ограничения на конструктивную часть концепции: «вот эта конструкция должна быть разбита на вот такие части-модули с вот такими между ними интерфейсами, чтобы добиться вот таких-то архитектурных характеристик».
В книге для рассказа используется диаграммная техника OPM (object-process modeling), в которой есть объекты, связанные друг с другом отношениями. И среди этих объектов выделяют функции (поведение), которые выполняются некоторыми инструментами (конструктивными объектами) над некоторыми пассивными объектами («молоток бьёт по гвоздю»). В руководстве по системному мышлению отмечался такой подход: в некоторых инженерных традициях не принято говорить о функциональных объектах, а принято говорить о поведении/функции, само же поведение-функция приписывается потом сразу конструктивным объектам, функциональные объекты при этом подразумеваются. Конструктивные объекты в упомянутой книге по системной архитектуре называют «формами». То есть вместо «камень::конструктив играет роль забивала::функциональный объект, а забивало забивает::функция связыватель::функциональный объект, роль которого играет гвоздь::конструктив» говорят короче: «камень::форма/конструктив забивает::функция гвоздь::конструктив». Таким образом, весь рассказ о забивале довольно легко понять: современная концепция использования — это архитектурная работа (функциональная декомпозиция и модульный синтез), как она обычно понималась раньше в системной инженерии, только на буквально один уровень в надсистеме (забивало нужно там). Отсюда и упоминание стратегии как отсылка к целеполаганию: концепция использования как раз говорит о выявлении функций целевой системы, которая сделает надсистему успешной.
Сегодня создание концепции системы уже не называют архитектурной работой, ибо современная архитектурная работа связана не столько с созданием концепции использования (хотя в ней могут быть заданы приемлемые значения архитектурных характеристик, архитектор этим живо интересуется и высказывает гипотезы об их значениях), сколько с созданием концепции системы в части верхнеуровневого задания конструкции системы такой, чтобы дальше можно было как можно более независимо разрабатывать отдельные части этой конструкции.
Конечно, современные и концепция использования, и концепция системы задаются не «деонтически» (как требования), а как гипотезы, эвристики, которые могут быть и изменены, если выяснится, что они не ведут к успеху. Поэтому раньше иногда говорили «требования архитектуры», а теперь предпочитают говорить «архитектурные решения».
Раньше, когда опытных разработчиков называли «архитектор», а создаваемую систему поначалу описывали в виде «набора требований», о концепции использования предпочитали не говорить как о важном рабочем продукте — ровно потому, что её не утверждали так серьёзно, как требования, она изначально воспринималась как «документирование гипотез». Кто-то приходил с идеей, затем оформлял идеи в виде концепции использования, и это был «мутный вопрос», в учебники по системной инженерии и стандарты он не попадал, ровно потому как казался «недостаточно строгим». Скорее, это был вопрос маркетологов, политиков, предпринимателей, кого угодно, но не инженеров — инженеры не выходили с идеей продукта, а если и выходили, то неформально, решение о выделении ресурсов на «серьёзную работу», то есть разработку требований, должны были принимать не они, а «кто-то с деньгами», но написать для этих «людей с деньгами» неформальные предложения должны были как раз инженеры.
Внешние проектные роли могли общаться с инженерами, но в формальный жизненный цикл однократной разработки это не попадало. Только некоторые школы системной инженерии соглашались, что разработка концепции использования входит в жизненный цикл инженерного проекта, в большинстве других школ в этом месте просто говорилось, что «надо написать текст на несколько страниц с основной идеей», не прояснялось как это делать и кто это делает. Когда приходят к инженерам, то уже кто-то сформулировал концепцию использования. Если концепцию использования и формулировали инженеры, которые искали себе работу, а потом «продавали» идею предпринимателям, то это не акцентировалось. Это не было «официальной» работой инженера, в то время как формулирование «требований» было как раз работой инженера, но считалось, что требования тоже — поступают от клиентов, менеджеров, кого угодно, но не от самих инженеров. Инженеры только «выполняют требования». Изменение требований, конечно, было возможно — но «приказ сначала выполняется, потом обсуждается». Изменение требований означало, что мы вышли за пределы предписанного «наукой» способа разработки «сверху вниз» (то есть поднимались по водопаду вверх!).
После того, как в проект вбрасывалась концепция использования «на трёх страничках», выделялись деньги — и проектом дальше занимался инженер по требованиям. Он делал реверс-инженерию надсистемы и документировал в виде спецификаций требований описание целевой системы, которая должна будет удовлетворить потребностям. Разработчики системы (прикладные инженеры, архитекторы, специалисты по инженерным обоснованиям) тем самым отсекались от общения с внешними проектными ролями. Это пытались исправить ходом на «модели требований», где кроме собственно формулировок требований пытались отметить, что кто из внешних проектных ролей говорит, на чём настаивает (переход на язык предметов интереса и интересов вместо языка конкретных значений, а также указание ролей, высказывающих свои интересы и их конфликтов, которые нужно как-то решать).
Потом «водопад» продолжал падать сверху вниз: требования (среди которых часто были и архитектурные решения, ибо системного мышления и понимания про разницу решений по вопросам снаружи границы целевой системы и вопросам внутри границы целевой системы не было) передавались системным инженерам-архитекторам, которые принимали решения по поводу концепций на следующих уровнях, и уже они формулировали требования на уровень ниже, то есть требования к подсистемам.
Скажем, идея нового самолёта приходила откуда-то «из бизнеса» (хотя неформально активно обсуждалась с инженерами), потом составлялись требования, потом архитектор делил проект на части и формулировал требования к двигателю, выбирая его концепцию: реактивный он будет, турбореактивный, или двигатель внутреннего сгорания для приведения в движение пропеллера. Эта «концепция следующего уровня» так даже не называлась, а архитектор просто выступал инженером по требованиям по отношению к архитекторам следующего уровня (архитектор самолёта выступал инженером по требованиям по отношению к архитекторам авиадвигателя).
В жизни всё работало совершенно не так, существенно итеративно, но обсуждалось именно так — строго постадийно. Ключевая модель концепции системы (с верхним уровнем как концепции использования, а дальше «прозрачный ящик) выглядела как «модель сэндвича»29, 2004 год.
Хлебом как раз были «слои требований». А поскольку требований оказывалось много разных, они начали получать разные названия:
Проблема была в том, что в этих картинках требования считались неизменными (раз и навсегда определяемыми), а моделированию позволялось изменяться по ходу всё лучшего и лучшего понимания предметных областей. «Заказчик» вроде как обязывался быть стабильным (как будто он сам не инженер! Как будто он обладал изначально совершенным знанием того, что ему нужно! Как будто говорил не гипотезы, а абсолютные истины!), а модельеры каждого уровня могли только торговаться по поводу удовлетворения этих стабильных требований. Эти спецификации ещё и ограничивали, как выяснилось, генерацию изобретательских идей30.
Требования в жизни оказались непрерывно изменяющимися на всех уровнях (водопад в реальности тёк снизу вверх во всех проектах!), но это не отражалось ни на каких диаграммах, в головах был «водопад», изменение требований наказывалось, было «сходом с дороги в бездорожье», а не нормальным ходом вещей. Если требования можно менять, то какие же они тогда «требования», в чём «долженствование»?
Основное время проводилось тем самым не за «требованиями» (которые потом в конце проекта можно было по-быстрому оформить, подписать — и сдать в архив, не читая), а за самыми разными моделями «чёрных ящиков», как раз modeling layer — и вот сами эти модели как рабочие продукты не показаны на диаграммах сэндвича, скрыты за словом слой/layer! Все эти use cases, концепции использования, разные варианты сценариев, функциональные диаграммы, списки внешних проектных ролей считались просто вспомогательными для получения требований.
Дальше переходили к моделям прозрачного ящика (показаны как очередной modeling layer, но уже уровня подсистем), по которым потом генерировались требования к подсистемам. Формально требования должны были идти дальше по цепочке «испорченного телефона», а неформально (чаще всего) они оформлялись — и без чтения шли в архив, а настоящая работа продолжалась с моделями систем, подсистем. Что надо было изменить? Объявить lean — не делать лишнюю работу, генерацию требований на основе готовых моделей! Оставить слои моделирования, выкинуть слои требований! Это бы и была «гибкая/agile методология разработки», а «анархия» убиралась при этом управлением конфигурацией (прежде всего — конфигурацией моделей: известно на любой момент времени, какие из версий моделей отражают последние договорённости в проекте). Но нет, несоответствие «водопада» и жизни объяснялось как «инженеры-разработчики системы, вы недостаточно стараетесь соответствовать идеалу», а не «менеджеры-организаторы проекта, вы очень плохо понимаете, как создают и развивают системы, ваши идеи в корне неверны».
Регламенты «водопада» требовали работы на основе требований, а не моделей — и поэтому приходилось изворачиваться, уходить от разных проверок. Было очень неудобно: работать «как предписано водопадом» не получалось, а нормально работать — непонятно было, как именно, теории не было, регламентов такой работы не было, изобретались неэффективные велосипеды, но зато проект хоть как-то шёл. Увы, во многих проектах до сих пор такая ситуация, исключением тут являются пока только проекты программной инженерии, но и те — в передовых компаниях.
Так, знание моделей use cases (тот самый modeler layer), из которых и извлекались требования, никуда от инженеров по требованиям не попадало кроме того, что оказывалось в требованиях. Эти требования шли дальше по цепочке от инженеров по требованиям — к архитекторам (в те времена архитекторы были — «опытные разработчики» следующего уровня, то есть разработчики концепции системы, а не концепции использования). И тестирование тоже было не того, что в моделях — тестирование было по тестам, которые делались на основе требований, люди занимались тестированием очень поздно по жизненному циклу (однократному!).
Встречи разработчиков с агентами, исполняющими внешние проектные роли считались злом, отвлекающим от работы, общаться с внешними проектными ролями предлагалось только инженерам по требованиям, «для эффективности». Разработки при этом шли очень медленно и дорого. Много действий происходило в проекте неформально, вне всяких регламентов и предписаний методологий разработки. Любое изменение в понимании системы и её окружения становилось адом: изменять часто нужно было требования, которые представлялись всем незыблемыми. То есть «изменение незыблемого» было постоянно, ощущалось это как непрерывная авария, непрерывный пожар в проекте.
Главным инструментом моделирования для получения требований стали сверхкраткие текстовые описания того, какое ожидается поведение системы в надсистеме (концепции использования), а затем модели use cases: формально представленные сценарии, по которым система как целое (или части системы как целое) взаимодействуют со своим окружением. Напомним, что в use cases некоторые акторы/агенты (живые и неживые, просто способные к взаимодействию) как-то взаимодействуют с системой, и показываются реакции системы, её поведение, которое и оказывается функциями системы. А требования? Они появлялись в результате документирования как-то уторгованного среди разных внешних и внутренних проектных ролей понимания того, как ведёт себя система (или подсистема) в разных вариантах взаимодействия с окружением.
В итоге совсем недавно было признано:
-
Важны не требования, а непрерывно уточняющиеся поведенческие модели (модели изменения состояний в ходе функционирования), то есть сценарии использования, диаграммы активности и другие виды моделей, отражающих поведение системы. Эти поведенческие модели отражают непрерывно меняющийся набор гипотез о том, что должна делать успешная система. Поскольку вопрос об успешности системы (успешности подсистемы, и т.д. по уровням), то в этих моделях должны учитываться и внешние проектные роли (а внутренние проектные роли вполне могут быть внешними проектными ролями для подпроектов: разработчик самолёта будет внешней проектной ролью по отношению к разработчику авиадвигателя).
-
Этими моделями должны заниматься сами разработчики без посредников в лице «аналитиков» или инженеров по требованиям. Прикладные разработчики с «архитекторами как опытными разработчиками», или сначала визионеры с эволюционными архитекторами, а прикладные разработчики с методологами/«functional designer»/«process engineer» потом (более современный вариант) — это уже не так важно, главное, что без «испорченного телефона».
-
Поскольку требований нет, то их и не надо менять, «брать назад поручение сделать, признаваться в ошибке». Меняется (уточняется!) понимание, отражаемое в моделях как гипотезах. Модели (и чёрного ящика, и прозрачного ящика) меняются «в рабочем порядке», анархии и неминуемых многочисленных ошибок при этом нет, ибо налажено управление конфигурациями, все версии учтены, исправления делаются только в актуальных версиях, за основу дальнейшей работы берутся только актуальные версии.
-
Людям в проекте при этом можно и нужно менять своё мнение (свои инженерные решения), аргументы (обоснование инженерных решений) берутся из моделей и основываются на результатах моделирования и проводимых экспериментах. Любая реализованная версия системы объявляется прототипом для следующей улучшенной и дополненной новыми «фичами» версии, даже если изготавливается всего один экземпляр: никакой экземпляр в эволюционной разработке не является последним. Если даже это летит ракета на Марс, то это не единственная попытка. Будет получено новое знание, и модели для следующей летящей на Марс ракеты поменяются. Каждая следующая ракета будет лучше предыдущей, или изменится так, что будет не хуже (помним, что эволюционный ландшафт динамический, и нельзя просто ничего не менять, чтобы оставаться приспособленным).
Что же сегодня предлагается «вместо требований»? Вместо — ничего, требования просто выкинули как лишний рабочий продукт. Незачем класть в архив то, что потом никогда не будет посмотрено. Ну, или нужно только для суда, определить формально «кто виноват» — «подписал требования». Но суд может и должен разбираться «по существу дела», а не «на основе сданных в архив документов». В суде ведётся расследование, а не просто берётся документальный факт из архива.
Но что будет «без требований» описывать систему на её границе? Набор постепенно уточняющихся и изменяющихся моделей и других описаний «чёрного ящика» (а иногда и «серого ящика», то есть на несколько системных уровней), по которым и ведётся разработка полной архитектуры. Но и это не последний исторический ход избавления от испорченного телефона и лишних рабочих продуктов.
Последний ход — это онтологическое моделирование в форме DDD, чтобы «попасть в предметную область» и получить bounded context (по факту — синоним «предметной области», набор типов предметов, которые задействуются в каких-то методах совместно). Да, и в «железной» инженерии онтологическое моделирование тоже есть, слова там важны, описывать предметы тоже надо. Вот пример на картинке:
А в какой форме описывать поведение? В форме use case? Да, так и делали — но потом оказалось, что поведение можно писывать сразу в форме тестов — чтобы проще было проверять это поведение. В программной инженерии это можно делать сразу на языке тестов, например, записывая сценарии в синтаксисе Gherkin системы тестирования Cucumber31. Вспомним, какие мы тут поминали рабочие продукты:
-
Сценарии (описывают поведение системы)
-
Требования (они лишние)
-
Проект/design с детальностью, достаточной для изготовления.
-
Тесты, которые проверяют выполнение требований, а если их нет — сценариев.
Выкидываем требования, а сценарии записываем в формате тестов — как то, что проверяется. Тем самым:
-
Если что-то меняется, вы сразу меняете тесты — и они же сценарии (вы же собираетесь проверять сценарии? Вот и записывайте их сразу в формате, удобном для проверки).
-
Отдельных сценариев и отдельных тестов, которые вы будете писать по сценариям — нет, это lean/элегантность. Ненужная работа не делается. Разработка ведётся так, чтобы удовлетворить тестам, они же «ожидаемая модель того, что будет происходить».
-
Отдельных сценариев и разрабатываемых по ним требований, по которым потом идёт разработка (создаётся проект системы с детальностью, достаточной для изготовления — например, программы для станков с ЧПУ или исполняемый программный код), к результатам которой потом разрабатываются тесты — нет. Тут lean, есть сразу тесты, они же — сценарии.
А если у вас какой-то обязательный в силу закона (требования!) стандарт, выполнение которого проверяется какими-то силовиками? Вы в ситуации «соблюдения закона»/compliance/«проверки соответствия». Попросите AI-систему перевести стандарт с требованиями в формат сценариев, который запишите на языке тестов, как мы подсказали32. Дальше всё как обычно: разрабатывайте систему, обоснование успешности разработки будет на основе прохождения тестов. Этот подход называется даже не TDD (test-driven development33), а BDD (behavior driven development34) как развитие TDD, и там ещё много вариантов (ATDD, acceptance test-driven development35 тут только один из возможных вариантов36, ибо встречаются и другие модификации примерно того же самого test-first подхода, причём test-first был когда-то отдельным термином, потом стал синонимом для TDD37: EDD, example-driven development38, SDD, story-driven development39, SpecDD, specification-driven development40 — все с одной и той же идеей записать желаемое поведение системы в какой-то форме, которая будет удобна для проверки или даже не будет требовать проверки, ибо система будет просто компилирована/синтезирована из спецификации желаемого поведения).
Behavior — это отсылка к методу/функциям, так что это прямая заявка на выполнение моделирования функций системы (впрочем, и функций подсистем) методологами/«функциональными проектировщиками», но результат документируется в виде сценариев поведения, автоматически трансформируемых в набор тестов для их проверки, сценарии пишутся по факту на языке тестирования. А что с поведением? Сценарий на языке тестирования как раз выражает поведение, которое надо проверить!
А что с новыми вариантами методов работы со сценариями использования в их классическом виде, например, Use Case 3.0? Они тоже остаются в прошлом41.
Почему же тогда тесты не назвать требованиями? Потому что это не требования, а тесты (и раньше тесты разрабатывались на основе требований, они ведь отличались от требований и назывались тесты/испытания, были программы испытаний). Ровно так же use case это use case, а не требования (они ведь и раньше различались): проблема не в переименовании, а в том, что перестали делать продукт «спецификация требований», который отражает описание чёрного ящика в деонтической модальности. Делаются гипотезы по поводу возможных таких описаний, эти гипотезы документируются в виде моделей, для которых можно организовать автоматическую проверку соответствия модели (то есть модели пишутся сразу как тесты, на языке тестирования). Эти модели (и тем самым тесты) не очень «требовательны», но «предположительны» и предполагают постоянное изменение по мере изменения общей проектной ситуации (внешние изменения в мире, изменения в бизнесе, изменения в понимании инженеров, учёт новых изобретений и т.д.).
Теперь разберёмся с постепенностью: это наша знакомая эволюционная/непрерывная разработка системы, она же создание MVP, а затем развитие системы. Раньше её описывали иногда как «инкрементальную разработку», а иногда как «итеративную разработку», противопоставляя их друг другу. И приводили самые разные картинки, которые нагло врали (из лучших, конечно, побуждений! Ибо приводимые метафоры не полностью соответствовали сути явлений). Вот типичные примеры этих кривых метафор:
Дальше возможны самые разные интерпретации — там можно услышать и «знаем, что хотим», и «не знаем что хотим», и «только через MVP», и «просто каждый раз ведите разработку с самого начала». Нет, там другие идеи:
-
Если рассматривать продукт, то есть идея инкрементальности: свойства продукта прирастают инкрементально в каждой версии (а уж за счёт новых частей продукта или переделок старых частей — дело десятое). Инкрементальность — это про продукт. Знаем ли мы, что там будет с продуктом? Не факт, но можно что-то такое представлять — это будет Roadmap. Инкрементальность разработки моделируется в roadmap: какие фичи (их так называет пользователь, «возможности», а вот для разработчика это «приращения функциональности продукта», инкременты продукта) в какой версии будут реализованы.
-
Если рассматривать процесс, то есть идея итеративности: мы выпускаем новые и новые версии продукта, каждый раз прокручивая какой-то инженерный процесс, то есть уточняя концепцию использования (определяем, что наша система будет делать — какие старые функции выкинем, какие новые добавим, какие ошибки исправим, какие оставим), затем (логически, в физическом времени тут итеративная совместная работа) уточняя концепцию системы (и архитекторы следят тут, чтобы на предыдущем шаге концепция системы уже была такая, чтобы какой бы следующий шаг ни был, изменения были минимальными — поэтому все эти безумные неверные картинки с MVP, проходящими велосипед-мотоцикл-легковушку-фуру надо выбросить).
-
Лучшие умы пришли к выводу, что нужна и итеративность, и инкрементальность — но они продолжали как-то противопоставлять шершавое и кислое. Нет там противопоставления! Это разговор про продукт и про процесс, два отдельных разговора.
Ошибка таких картинок была в том, что они опирались на устаревшие трактовки инженерного процесса, ещё во времена до понимания эволюционной архитектуры, во времена «старой архитектуры», где был «опытный разработчик» и ходили идеи «прототипов» в «спиральной модели разработки». Эти прототипы надо было делать «для получения информации» — и затем выкидывать. Эволюционная архитектура сразу поставила вопрос о том, что архитектор не принимает важные решения, которые поменять потом нельзя, если всё не выкинуть. Нет, архитектор старается сделать так, что ничего выкидывать целиком не придётся, все изменения будут локальны, переписывать « с нуля» не надо!
Идея картинок была в том, что «растёт функциональность», она инкрементально добавляется по сравнению с MVP, но архитектора за такое надо уволить сразу, такого не должно быть! Архитектура, понятно, тоже меняется! Но посмотрите: во всех этих примерах видно, что конструкция системы на «правильных» вариантах кардинально меняется, её надо переделать полностью! Это фиаско, провал, неудача, прототипирование с их выкидыванием сегодня — не лучшая практика. Можно думать и так, что в любой момент времени в проекте ничего нет, кроме прототипа, любая версия — прототип, гипотеза о том, что надо было бы делать, дальше получаем отклики от внешних проектных ролей, меняем прототип на следующий, делаем инкремент в следующей итерации. Но прототипы никогда не выкидывают целиком, переделывать надо какие-то отдельные модули, но не всё вообще! И если это не так, то это провал, фиаско, неудача архитектора (ну, или надо признать, что «проект оказался неудачным, закрываем его, делаем вираж/pivot, начинаем заниматься другим продуктом»).
Поэтому после прихода эволюционной архитектуры начали аккуратно писать про «эволюционную разработку», могут обсуждать инкременты и итерации, но вот противопоставлять итерационную и инкрементальную разработку — этого уже никто не делает. Как и не выкидывают прототипы целиком. Хотя иногда выкидывают не только прототипы, но и вполне рабочие текущие версии –но это очень серьёзное и очень редкое решение.
Подробней это разбирается при обсуждении работы «эволюционного архитектора». Конечно, так («эволюционный архитектор») его никто не называет, называют просто «архитектор», но и старого «опытного разработчика» тоже могут называть «архитектор», да и «функционального архитектора» могут называть «архитектор», хотя он методолог, да и результат его работы могут назвать «архитектурой». Помним пример из руководства по методологии: архитектурой искусственной нейронной сети называют её рассмотрение как протекание потоков данных через какие-то функциональные блоки. Архитектурным описанием нейросети обычно считают или dataflow диаграмма или псевдокод алгоритма обработки данных нейросетью. Но это не современный вариант понимания «архитектуры», ибо про модули тут вообще не идёт речь, это «функциональная архитектура», которая в современном архитектурном языке вообще отсутствует. Каждый раз проверяем: про какую архитектуру и какого архитектора идёт речь!
Обычно мы сразу не очень понимаем, чего хотим, и добавляем какие-то кусочки — и всеми этими кусочками можно пользоваться. Если мы делаем карандаш, то на первой итерации в первой же версии мы делаем карандаш из глины и угля в бумажном пакетике, затем потихоньку меняем глину на пластик, уголь на графит, пакетик на картонную коробку. Сохраняем что можно, меняем всё на более функциональное. Или даём пользователю шикарный современный графитовый (или тоже пластиковый) грифель, он им пользуется, но пачкает руки. Добавляем пластиковый корпус к грифелю, но пачка карандашей рассыпается по столу и неудобно продаётся. Добавляем картонную коробку. Понимаем, что можем положить в коробку и точилку, чтобы её покупали у нас, а не у конкурентов — и делаем её той же расцветки, что и коробку, чтобы уж точно не путали «наше» и «не наше». Модель карандаша при этом существенно меняется, при этом поначалу и карандаша нет как продукта, а потом карандаш становится только частью продукта. Это две стратегии получения карандаша (и одна даже вышла на коробку и точилку в придачу к карандашу), но может быть реализована какая-то смесь двух стратегий, или обе сразу (это ж всё гипотезы на каждом шаге!), всё зависит от того, сколько у нас ресурсов, сколько мы можем опробовать вариантов. И надо помнить в ходе всего проекта: «обычно мы сразу не очень понимаем, чего хотим» сохраняется в любой момент разработки, а не только в самом её начале! Итерации не прекращаются, инкременты не прекращаются! Разработка и выпуск разных версий продукта непрерывны, эволюционны!
Этот подход (беседа клиентов и других проектных ролей с разработчиком, документирование гипотез разработчика с предложением тестов вместо требований) был использован даже для «неживых программистов», а именно для генератора кода TiCoder42 (test-driven interactive coder), который был разработан на основе больших языковых моделей ещё в 2022 году. В этой работе уточняли намерение человека-программиста, подтверждая или опровергая предложения TiCoder и получили соответствие кода намерениям в 90.4% случаев. Метод/workflow назвали TDUIF (test-driven user-intent formalization). Сегодня большие языковые модели делают такое (и лучше) «из коробки», это уже стандартный путь разработки. Код компьютер-разработчик напишет лучше программиста-кодера, но для него пока нужно поставить задачу. Формализовать задачу до уровня, достаточного для однозначного решения задачи в форме кода программы можно в ходе диалога (непрерывное уточнение задачи), а не просто написав какие-то требования и утвердив их. Нет, вы будете формулировать гипотезы по поводу того, как должна вести себя программа — и оценивать результаты, затем корректировать гипотезы. Сегодня это штатный метод работы в software engineering (мы говорили о vibe coding), но это становится штатным методом работы и в инженерии системы другой природы — умеющие поддержать разговор на естественном языке большие языковые модели используются и в машиностроительных САПР (CAD/CAM/CAE). Эта сфера столь стремительно развивается, что мы не даём тут ссылок: ситуация изменяется еженедельно, исследуйте вопрос о готовности инструментов к такой работе сами.
Рассказанная здесь история про отказ от требований произошла главным образом в программной инженерии (включая, как видим, и работы по автоматизации работы программных инженеров), в меньшей мере инженерии киберфизических систем, ещё меньше в строительстве, а во многих других сферах оказалось, что «когда караван поворачивает, хромой верблюд оказывается впереди»: там не наладили работу по требованиям, поэтому отказа от требований и не будет.
В проектах зато стало нужным разработчикам кроме моделирования самой системы «от границы внутрь» моделировать ещё и внешнее поведение системы в плотном контакте с внешними проектными ролями, которые знают поведение системы «от границы наружу» (стандартный ход системного мышления: сначала смотрим функцию «наружу», и только потом конструкцию «внутрь»). В этом плане в огромном числе прикладных инженерий (скажем, в медицине, образовании, политике) отсутствие требований не означает современного (SoTA, state-of-the-art) состояния, ибо нет и моделирования, нет создания концепции использования, нет выражения модели в виде, готовом к тестированию (на языке какой-то системы тестирования).
В жизни вы сегодня увидите и отсутствие каких-то моделей и требований («доинженерное» состояние в какой-то прикладной инженерии), и работу с требованиями (скорее всего, в классической «железной инженерии»), и современную ситуацию с моделированием концепции-как-гипотезы вместо требований (скорее всего, во фронтирных IT-компаниях). Это как пелетон/пелотон, когда велосипедисты вдруг растягиваются на несколько километров — и у первых из них одни проблемы, у плотной серединки другие проблемы, а у плетущихся в хвосте полное непонимание и проблем лидеров, и проблем «середнячков», они безнадёжно отстали и им бы просто не сойти с дистанции.
Вам же нужно понимать, в каком месте пелетона вы очутились, и не удивляться, если в разных подпроектах вашего проекта будут приняты разные решения по поводу методологии разработки: где-то доисторические «ещё до требований» (и без моделей), где-то «всё только с требованиями», а где «после требований, с гипотезами как отдельными моделями», где-то сразу DDD-BDD (и варианты для систем разной природы, ибо DDD-BDD хорошо описано только для программной инженерии). Дальше будем писать BDD, ибо самое важное в этих всех вариантах то, что для тестирования нужно формально описать поведение системы, в форме, удобной для проверки. Не будем каждый раз говорить TDD, BDD, ATDD, EDD и самые разные другие варианты подхода test first, то есть «формально записанное ожидаемое поведения системы, выполнение которого легко проверить — сначала».
А что там в киберфизических системах? В Tesla каждый автомобиль идёт по заводу уникальным маршрутом, ибо внутри завода сосуществуют разные версии каких-то отдельных операций. Поэтому тестирование идёт на входе и на выходе каждой производственной ячейки (ибо везде что-то может пойти не так). Но что с тестированием автомобиля? При сертификации ведь обычно берётся какой-то автомобиль, сертифицируется (проходит полную программу испытаний для получения государственного сертификата безопасного транспортного средства), а затем серийно выпускается на основе этого сертификата. Что же с Tesla, где каждый выпускаемый автомобиль имеет уникальную конструкцию, при этом прошёл через уникальный маршрут на заводе? Ну, тестируется каждый автомобиль, проходит всю программу испытаний. Это чуть дольше и дороже, но надёжно — и при надлежащей автоматизации не так уже дольше и дороже. Неприятности с выпущенным недотестированным автомобилем обойдутся дороже.
Что касается обучения практикам системной инженерии: если целитесь попасть в середину пелотона, то учиться сегодня нужно фронтирным практикам. Пока выучитесь, как раз в середину пелотона и попадёте. Если учитесь практикам середины пелотона, «мейнстриму», то в момент работы будете уже в хвосте. Вам нужно разобраться с мета-мета-моделью фундаментальных методов, чтобы с их помощью уже разбираться с винегретом мета-моделей прикладных методов уровня культуры предметной области («из учебников прикладной инженерии» типа цитируемых в текущем разделе учебников инженерии киберфизических систем и программной инженерии) или даже уровня культуры одной организации («из руководств и стандартов фирмы», даже если это какая-то очень крупная фирма, например NASA или MITRE с их существенно отличающимися руководствами по системной инженерии, безнадёжно устаревшими, поэтому туда лучше и не заглядывать). Не так важно, что вы делаете (помним, что эволюция, в том числе эволюция методов, приводит к множеству очень похожих по характеристикам субоптимальных решений), как важно, что вы понимаете, что именно вы делаете и почему именно так, и почему вы считаете, что вы попадёте в текущий субоптимум, или даже следующий уровень субоптимума, а не просто провалитесь в какой-то из прошлых давно забытых субоптимумов.
Моделирование: мой «испорченный телефон»
Опишите три «испорченных телефона» в вашей организации и организациях, откуда пришли исполнители внешних проектных ролей. Напишите, кто какие описания разрабатывает и кому передаёт, чтобы информация от её источника дошла до реального продукта.
| Номер п/п | Цепочка «испорченного телефона» | Длина цепочки |
|---|---|---|
| Пример. | Аналитик клиента Маша общается с мастером клиента Олей, которой нужны особые сепульки и пишет «Запрос на разработку сепулек». Аналитик Вася на основе «Запроса на разработку сепулек», пишет «Аналитический отчёт о потребностях клиента Маши в сепульках» (об Оле он не знает, для него клиент — Маша). Аналитик Петя на базе «Аналитического отчёта о потребностях клиента пишет» «Требования к сепулькам». Начальник отдела сепулек Саша пишет документ «Основные принципы сепулек для клиента Маши» (и там концепция сепульки с замечаниями по архитектуре). Разработчик сепулек Женя делает информационную модель сепульки, тестировщик Валя пишет тесты. Технолог Даша изготавливает и тестирует сепульку. | 7: Оля-Маша-Вася-Петя-Саша-(Женя+Валя)-Даша |
| 1. | ||
| 2. | ||
| 3. |
TEST концепция использования и концепция системы
Отметьте те высказывания, которые относятся к концепции использования двигателя как целевой системы.
--- Топливо под воздействием сжимающего его пары поршня загорается, и горячие газы начинают толкать поршень с большой силой в обратном направлении, это движение через коленвал передаётся на вал двигателя и может быть использовано для движения автомобиля. Для предотвращения просачивания горячих газов между стенками цилиндра и поршнем используются поршневые кольца. ### Нет, это концепция системы: как устроена система двигателя внутри, чтобы выдать наружу требуемую функцию.
+++ Для движения автомобиля мы используем двигатель внутреннего сгорания, который будем заводить от стартера, топливо он будет получать из топливной системы, а энергию для движения мы будем отбирать с вала двигателя, через коробку передач. ### Да, это концепция использования: как будут использовать двигатель в надсистеме.
+++ Двигатель в составе помпы как насосного агрегата будет управляться через пульт, общий для насоса и двигателя, а заводить его будут заводным шнуром вручную. ### Да, это концепция использования: как будут заводить двигатель в надсистеме, как им будут управлять.
--- Нам нужен крутящий момент на валу достаточный, чтобы полтонны груза на тележке, которая и сама весит полтонны, можно было поднимать в гору со скоростью 15 км/в час. Поэтому мы будем использовать не двигатель внутреннего сгорания, а бесщёточный электродвигатель. ### Нет, это концепция системы: рассматривается устройство двигателя в заданной надсистеме, и выбирается между устройством его как двигателя внутреннего сгорания и электродвигателем.
Разработка концепции использования и концепции системы
Концепция использования разрабатывается прикладными методологами и архитекторами, одобряется или отвергается визионерами (полностью или в каких-то частях, возможно в развёртке по времени — technology roadmap43). Визионеры — это чаще всего те, кого называют intrapreneur, корпоративные предприниматели44. Их главная функция — предсказать NPV45, то есть насколько проект будет прибыльный. Нынешние экономические теории предпринимательства не слишком подходят для описания этой роли, потому как они подчёркивают разные стороны того, что в современном предприятии расписано на более мелкие детальные роли — Шумпетерский предприниматель занимается «творческим разрушением», а мы тут создаём, Кирцнеровский предприниматель внимателен к возможности заработать, тут это более применимо46, Кантиллион подчёркивает принятие на себя риска — хватает ролей, которые принимают риск во внутрикорпоративном контексте, Друкер подчёркивает новизну метода47, но за новизну отвечают обычно инженеры в команде. Так что в нашем случае речь идёт о роли визионера, который отслеживает прибыльность проекта, чтобы в разработку было вложено меньше ресурсов сейчас, чем заплатят клиенты потом — с учётом всех неопределённостей. Если что-то убыточно, то просто не будем этого делать, визионер не даст — это его главная роль.
Вот как это всё намеренно запутанно изображается в книге ««Systems Architecture. Strategy and Product Development for Complex Systems»:
Концепция использования тут только оцениваемая в возможных деньгах идея, которая постепенно детализируется в концепцию системы (на диаграмме она по старинке названа «системная архитектура»). При этом разработчики и визионеры (интерес визионеров в максимизации потока денег от продукта, чаще всего эти роли исполняются людьми на должностях product owner, product manager) и бизнесмены (интерес бизнесменов в максимизации стоимости компании, их продукт — компания в целом, их клиентура — инвестура, акционеры/инвесторы) обсуждают business case, который можно считать вариантом бизнес-модели, «концепция выкачивания денег из проекта». Они должны достичь соглашения по концепции использования с учётом концепции системы: денег от продаж (их можно прикинуть по концепции использования — сколько удастся продать продукта с такими свойствами) должно хватить на разработку и изготовление плюс прибыль, свойств системы (пользовательской функциональности плюс архитектурных характеристик, о которых будет чуть позже) должно хватить, чтобы запросить эти деньги у клиентов. Концепция системы (тут это system architecture) даёт оценку, во сколько это всё обойдётся компании — сколько будет стоить разработать и изготовить систему. Всё это, разумеется, гипотеза: реальные клиенты могут заплатить или не заплатить (или продавцы могут не найти клиентов, «плохой маркетинг»), реальная система может соответствовать или не соответствовать ожиданиям клиентов (плохо спроектировали, криво изготовили, не смогли наладить в эксплуатации).
В любом случае, хорошо видно, что концепция использования разрабатывается совместно командой инженеров целевой системы и менеджеров как инженеров предприятия и маркетёров как инженеров сообщества клиентов. Они все должны договориться, чтобы проект случился. Если обсуждается проект создания провайдера сервиса, то тут ничего не меняется, тот же разговор про системы, те же роли — только чуть по-другому проведены границы в графе создателей (сервис-ориентированная работа — это когда работаем по нашему методу и нашими инструментами с целевой системой, принадлежащей не нам, а принесённой клиентом).
Весь процесс согласования идёт между ролями, а не агентами. Концепция использования может прийти и извне фирмы, от её клиентов, ей может озаботиться какой-то основатель стартапа, работающий сразу во множестве ролей, она может быть вычитана в прессе, подсмотрена у конкурентов (тут близко к пониманию Kirzner, что визионер «алертен/внимателен» к возможной прибыли, не пропустит такую возможность) — и далее просто улучшаться-дорабатываться в какую-то конкретную концепцию системы, или архитектуру (в старом её значении, на картинке из книги именно так). Это самое важное: творчество не имеет конкретного источника, нет ролей, назначаемых на творчество.
Часто встречается ровно обратное: кому-то приходит в голову концепция системы, что какие конструктивные объекты могут выполнить ту или иную функцию, и надо придумать концепцию использования. Это тоже бывает. В любом случае, проекта нет, если известна только концепция использования (скажем, «скатерть самобранка, вкусно кормит всех за один рубль» — без рассмотрения концепции системы, которая может это делать) или наоборот, только концепция системы («я придумал глюклу, которая очень дёшево глюкает, если её заправлять глюкагелем — давайте придумаем, куда бы это можно было пристроить?»). Нет, проект начинается только после первичной проработки концепции использования, рассматриваемой как бизнес-кейс, и концепции системы, нужной для оценки возможностей создать целевую систему по цене, осмысленной для бизнес-кейса. Всё это гипотезы, конечно, в ходе проекта идёт непрерывное уточнение оценок — и изменение проекта по ходу этого уточнения оценок, а иногда проект и закрывается, если оценки показывают коммерческую бесперспективность.
Идеи тут приходят в голову отнюдь не только «стратегам», «визионерам», «бизнесменам» или «архитекторам». Она приходит в голову любым инженерам: людям, которые пытаются что-то сделать, как-то приспособить для своих целей предметы окружающего мира. Нет роли, приватизировавшей творчество, приватизировавшей предпринимательство по-Шумпетеру или Друкеру, или по любому другому (чаще всего — бытовому, у каждого человека своему) пониманию. Современное предпринимательство распределённо по частным ролям, выполняемым разными людьми — визионерами, бизнесменами, проектировщиками (инженерная идея чаще всего — его!), инвесторами, а также всеми остальными ролями, нужными для предложения проекта и оценки его возможного успеха. Ровно поэтому мы табуируем слово «предприниматель» и обсуждаем более специфичные роли, например, роль визионера как оценивающего рыночный успех продукта, описываемого концепцией использования и продающегося по цене, которая окупит разработку, изготовление, а также затраты на маркетинг и продажи. Конечно, всё значительно сложнее — так, интересует не просто «цена», а полная стоимость владения — клиент ориентируется при покупке на неё, а ещё волнует разница вкладываемых/инвестируемых в разработку денег сейчас против получаемых от продаж готового продукта через некоторое время, идея NPV48.
Первичные тесты на полноту системного описания (какая функция в надсистеме требуется, какой эту функцию выдаст функциональный объект, какой сервис какое сочетание конструктивных объектов может выдать на базе каких физических принципов, как это будет расположено в пространстве, какие стоимостные ограничения, и помним, что кандидат в продолжение системного описания — это выход в граф создателей, какие работы нужно будет выполнить, чтобы это сделать) может сделать любой человек (со своими компьютерами), любая организация из нескольких человек, хотя речь может идти не обо всей системе, а только о части системы, ограниченной предметной областью метода этого агента.
В современной системе разделения труда появилось множество должностей (иногда их называют «ролями в кросс-функциональной команде», что вносит дополнительную путаницу), в букет профессиональных проектных ролей которых входит работа с детализацией и уточнением концепции до полной архитектуры на уровне системы в целом. Прежде всего это
-
product manager (иногда product owner), он отвечает больше за business case, кроме того, что он в инженерной команде визионер/visionary, он ещё и операционный менеджер — принимает решения о том, какие фичи из бэклога надо реализовать в текущей итерации, чтобы увеличить поток денег, то есть назначает работу инженерам. В целом product manager отвечает за то, чтобы можно было получить деньги за сделанное инженерами. Если это «лучшая в мире система», но она никому не нужна настолько, чтобы за неё платили больше, чем стоит её разработка, то это провал в работе product manager. На всякий случай теперь повторим (ибо это частая ошибка): визионер ничего не разрабатывает, он или одобряет, или не одобряет выделение ресурсов на разработку тех или иных фич. Инженеры-разработчики часто увлекаются и пытаются что-то разработать, что клиенты могут (по ожиданиям визионера, это его обязанность — иметь на эту тему ожидания) и не оплатить. Тогда это будет за счёт инвесторов команды инженеров, за счёт собственников. Это плохо, поэтому инженеры не работают без согласования с визионером. Визионер выставляет приоритеты, какие фичи нужны клиентам (рынку) больше, какие меньше — тем самым выдаёт ориентиры операционному менеджеру для планирования ресурсов и отслеживания их реального выделения на работу. Если речь идёт о должности product manager, то это объединяет роли визионера и операционного менеджера. Конечно, руководство фирмы всегда может на должность product manager повесить дополнительные роли — любые роли разработчика или даже архитектора. Мы тут в руководстве наставляем о том, что надо сделать, о чём в проекте подумать, какие роли это делают. А уж как эти роли разложить по ограниченному числу актёров (многие из которых ещё и плохо умеют эти роли выполнять — что не мешает руководству поручить им эти роли играть), это надо смотреть в каждом отдельном проекте.
-
прикладной разработчик, инженер в какой-то предметной области — чаще всего это предметная область клиента плюс предметная область самой разработки. В программной инженерии это программист/software engineer, который разобрался ещё и в предметной области, которую поддерживает его софт, то есть в business domain. Функциональные use cases более-менее подробно прорабатывает именно он, все концепции на эту тему — у него. Мы в руководстве учитываем, что и «прикладной разработчик» тоже относится к нескольким ролям: прежде всего это методолог (проектировщик функций/процессов, functional/process designer), собственно проектировщик (designer, в машиностроении часто — конструктор), технолог, оператор. Включение оператора в разработчики объясняется поговоркой «ты это построил, ты это и эксплуатируй», «you build it, you run it!», она служила выражением смены культуры разработки, где команда инженеров-разработчиков (Dev) сдавала софт для его разворачивания, введения в эксплуатацию и обеспечения работоспособности команде операторов (Ops), но движение DevOps изменило эту культуру, и операторы стали членами команды «разработчико-операторов», в 2016 году появился этот слоган49. Современная версия DevOps — это признание роли инженера внутренней платформы разработки, но вот работают с этой платформой, включая ввод в эксплуатацию и поддержание эксплуатации как раз операторы из команды разработчиков. Операторы на переднем крае команды разработчиков, они первые видят, что там происходит у клиентов, поэтому идеи новых проектов часто приходят в команду через операторов.
-
архитектор, который прорабатывает те части концепции, которые отвечают не столько за функциональные характеристики, сколько за архитектурные — всякие -ости/-ilities, в том числе и за такие характеристики, как возможность что-либо быстро поменять в самой архитектуре (evolvability) или независимость в работе отдельных групп прикладных разработчиков, если их предметы немного различаются.
И тут в классической «железной» инженерии ситуация отличается от ситуации в современной программной инженерии. У «железячников» (вернее, создателей киберфизических систем, там «железо» с софтом) концепцию в части выполнения функциональных требований (в большинстве школ классической «железной» системной инженерии допускают существование требований до сих пор, там в голове «водопад» и «испорченный телефон») до архитектурных подробностей выполняет архитектор как «опытный разработчик, знаток всех ролей», а дальше его работу подхватывают и детализируют архитекторы как «опытные разработчики, знатоки всех ролей» более низких системных уровней или прикладные разработчики по инженерным дисциплинам. В разработке корпоративного софта эти роли уже разошлись по разным людям: с функциональными характеристиками системы и соответствующими решениями по концепции использования разбирается прикладной разработчик какой-то отдельной команды, а архитектор всего проекта отслеживает только соблюдение архитектурных характеристик, в том числе координирует, чтобы подсистемы, которыми занимаются несколько команд прикладных разработчиков, могли взаимодействовать друг с другом. Так что роль архитектора понимается в разных инженерных методах по-разному, и нужно уточнять:
-
Или архитектор — «опытный разработчик», занимается разработкой всех концепций, а затем всей архитектурой как концепцией системы, и потом раздаёт задания прикладным разработчикам (это в киберфизических системах, и там лаг отставания по сравнению с программной инженерией в десяток лет),
-
Или архитектор — эволюционный архитектор, занимается разработкой концепции системы в части выделения модулей и интерфейсов (архитектурные решения), а в концепции использования предусматривает необходимые архитектурные характеристики (они описывают поведение системы в целом, но аспект не прикладной функциональности, подробности будут в нашем руководстве чуть позже). Затем архитектор разъясняет (менторинг) эти решения разработчикам и отслеживает (надзор, governance) их работу на предмет выполнения принятых им архитектурных решений, время от времени меняя эти решения (это тоже гипотезы!). Скорее всего, к этому пониманию придут через несколько лет и в инженерии систем самой разной природы, не только программной инженерии.
Вот эта неопределённость с ролями, разрабатывающими концепцию использования и концепцию системы на самых первых шагах проекта, ещё до формального выделения ресурсов на проект. Все эти идеи обсуждаются неформально, ресурсы не выделяются, пока не будет назначен какой-то визионер и ответственный за ресурсы, часто в одном лице — product manager, иногда это просто project manager, но тогда это чаще всего «просто менеджер», плохо (не как инженер!) разбирающийся в целевой системе, то есть плохо разбирающийся в особенностях продукта, и тогда должен быть найден ещё и исполнитель роли визионера, который глубоко разбирается в продукте и предметной области применения/использования этого продукта. Визионер — это прежде всего инженерная роль. Продуктовый менеджер совмещает инженерную и менеджерскую роли.
Если у вас очень большой проект (скажем, проект выпуска электромобиля), то в вашей разработке вряд ли будет какая-то глубокая концепция всей машины. Архитектор нарежет этот электромобиль на разные подсистемы, которые будут реализовываться разными командами, у этих команд будут свои методологи, отвечающие на вопрос «как оно у нас всё работает». Кто-то будет заниматься мотор-колёсами, кто-то подвеской, кто-то аккумуляторным матом. Мы уже говорили, что архитектор отслеживает, чтобы зависимости между всеми частями системы были минимальными, но не нулевыми (если нулевые — то не будет взаимодействующих частей системы, эмерджентные свойства не появятся. Независимые друг от друга мотор-колёса, салон, подвеска, аккумуляторы — не поедут как единый целый электромобиль). Но вот команд будет несколько, и у них будут для своих подсистем отдельные концепции использования. Для многих таких подсистем это будет выходить на пользовательский уровень — скажем, «новая фича по регулированию температуры в салоне», «новая фича по ускорению времени зарядки аккумуляторов» с одной стороны могут быть описаны как фичи автомобиля в целом, с другой стороны — отнесены к каким-то модулям автомобиля, то есть отданы на откуп каким-то командам.
В современной разработке признали, что для сложных систем не существует подробного функционального описания, охватывающего все особенности поведения. Эти описания отдаются на откуп командам, которые занимаются «профильными» модулями — если речь идёт о температуре в салоне, то на уровне автомобиля в целом нет методолога, который бы этим занимался, а вот в команде, которая занимается автомобильным салоном такой методолог есть. Поэтому в современной разработке сложных систем на верхнем уровне работает визионер (ему надо продавать! Он согласует или не согласует новые фичи и порядок выпуска их в новых версиях системы) и архитектор, которые грубо прикидывают, какие команды могли бы реализовать эту функциональность — и отдают разработку «вниз», на уровень этих команд (возможно, нескольких команд в кооперации). Это резко контрастирует с идеями прежних подходов. Один из вариантов тут — методология разработки SAFe50, которая не слишком радикально отходит от «водопада» и не является совсем уж гибкой методологией разработки, но хотя бы признаёт, что нельзя проводить систему через общие для неё «гейты»51:
-
Раньше была идея, что какой-то «опытный разработчик автомобилей» (главный конструктор с помощниками) декомпозирует автомобиль на части, прописывая необходимые характеристики частей, формулирует требования и поручает команде разработать их части в строгом соответствии с требованиями. Нет, это бы означало, что у главного конструктора по части функциональности частей системы более чем энциклопедические познания. При такой декомпозиции «сверху вниз» наверняка будет наделано много ошибок из-за банального неучёта SoTA предметной области, в которой работают команды. Поэтому никакой «глубокой декомпозиции функций» в сложных проектах сейчас не делается. Архитектор с визионером проводят совещание по поводу предложенной кем-то (только что обсудили, что идеи могут приходить от самых разных ролей) идеи новой фичи, нового инкремента, а потом отдают проработку этой идеи профильным командам. И функциональные проектировщики работают там, «внизу», а не «в штабе».
-
Раньше была идея, что все требования по всей системе надо собрать, проверить на совместимость, оценить их реализуемость, а уж затем всей пачкой отдать командам на реализацию. Нет, сейчас нет «всех требований к системе». Архитектор удерживает «на штабном уровне» какие-то архитектурные характеристики, но вот целая концепция использования существует на верхнем уровне только весьма неподробная. Подробная концепция использования разрабатывается главным образом методологами команд, причём она разбита тем самым на отдельные части, которые очень редко собираются вместе — и это задача архитектора разбить систему (и тем самым команды в силу обратного манёвра Конвея) на части так, чтобы не возникало коллизий, чтобы команды могли работать независимо. Каждая команда тем самым владеет (то есть может вносить изменения, никого не спрашивая «сверху») своей концепцией использования, и никто даже не делает вида, что эти концепции использования каким-то чудом собираются в «общую концепцию использования всей системы», это бессмысленно, этой сборкой никто не будет пользоваться, делать так — неэлегантно, не lean, это лишняя работа. И дальше команды свои частные концепции использования пишут в формате, который легко превращается в формат описания испытаний.
Самые разные учебники инженерии, стандарты инженерных процессов, учебники менеджмента всегда невнятны в том, как выполняется самое начало работы над проектом, когда о продукте мало известно и в проекте максимальная неопределённость. Системное мышление даёт мета-мета-модель, как рассуждать о такой ситуации, системная инженерия даёт набор ролей и набор рабочих продуктов, которые в такой ситуации надо готовить. А уж когда понятно (гипотеза! Гипотеза о том, что понятно! Её надо проверять!), чем в проекте заниматься — вот тут уже много литературы, тут уже много знаний, тут уже проще.
В ТРИЗ52 есть теория развития технических систем, которая как раз обсуждает общие закономерности эволюции их конструкции по мере накопления инженерных знаний. Основная закономерность развития базируется на понятии идеальной системы: когда конструктивных элементов нет вообще, а функция таки выполняется (обычно какими-то другими частями конструкции: например, корпус какого-то устройства может служить заодно и механической защитой, и радиатором). Но обычно всё-таки нужны какие-то конструктивные/модульные части системы, чтобы добиться выполнения ими во взаимодействии через их интерфейсы какой-то требуемой функции на границе системы. Концепцией/concept системы и называют такое решение изобретательской задачи, именно поэтому ТРИЗ (теория решения изобретательских задач) стал одним из первых методов в инженерии, который целевым образом стал изучать концепции системы. От существовавших во времена появления ТРИЗ (начало работы над этим подходом — 1946 год) методов инженерии ТРИЗ отличался прежде всего тем, что требовал представить сначала функцию системы в виде функционального разбиения на 5-7 подфункций (ибо если меньше, то мало пространства для творчества, а если больше — слишком много нужно внимания, чтобы что-то не потерять), а затем после стадии генерации идей «изобретения» конструктивное разбиение сразу давалось в виде компоновочного чертежа, отражавшего и конструкцию, и размещение. После этого «изобретения» можно было уже выполнять традиционную инженерную проработку полученной концепции.
Разработка концепций (использования для надсистемы, системы — для целевой системы) — изобретательская, творческая задача. В её основе — системное творчество (напомним, что в руководстве по системному мышлению был такой подраздел). Решением творческих задач занимаются все участники проекта, каждый в своей предметной области. Весь вопрос только в том, проходит ли это решение интуитивно, или по какому-то методу. ТРИЗ как раз и предлагал один из таких методов разработки концепции (и там активно использовались свойства нейронной сети человеческого мозга, в том числе там были приёмы развития творческого воображения). Но современная инженерия вся основана на подобных методах, разве что сам момент «изобретения» концепции в ней не акцентируется — это рутина, все должны быть изобретателями, творцами, предлагать новые решения (хотя понятно, что лучше изучить какие-то эффективные уже существующие решения, чем предложить своё новое без проверки того, что оно лучше уже имеющихся. Поэтому инженеру нужно глубокое знание уже существующих инженерных решений. Ну, или этим знанием вместо него будет обладать AI, которому надо будет дать достаточный контекст, чтобы предложенное решение было уместным).
Разработка концепции идёт в цикле:
-
Определение функции, которую нужно реализовывать конструкцией, по возможности нейтрально по отношению к конструкции. Это довольно трудно, ибо требует абстрактного мышления. «Изменение/поведение как таковое» трудно представляется без конкретного объекта или их совокупности, который вызывает это поведение. Мы подробно разбирали трудности этого шага в руководстве по методологии.
-
Порождение альтернативных идей по конструкции, реализующей функцию. Это метод творческого воображения, изобретения, культурного заимствования. Концепции придумываются «с нуля», как «новое изобретение», или предлагаются «умные мутации» потенциальных улучшений к уже имеющимся изобретениям, или просто берутся какие-то известные уже решения из предыдущих проектов, возможно, не ваших, поэтому тут нужно «спросить у AI», заимствовать решение из культуры — ну, или таки изобрести что-то потенциально лучшее.
-
Выбор (рациональный, в условиях неопределённости) из альтернатив предыдущей стадии, называемый в системной инженерии прохождением развилок/trade-off studies. По-русски тут подчёркивается аспект выбора (можно выбрать одно, или другое, или третье решение/solution, то есть пройти развилку), по-английски термин подчёркивает не столько конечный выбор, сколько «компромисс» в этом выборе, «выбор сделан, но никто им не доволен, ничьи цели не достигнуты».
Этот цикл может быть бесконечным по времени на какой-то итерации, такая ситуация встречается чаще, чем можно себе представить, она называется analysis paralysis — застревают люди чаще всего на стадии выбора из квазиоптимальных альтернатив, хотя бывает иногда и не аналитическое застревание, а синтетическое: на стадии генерации альтернатив, ибо хотят сделать что-то типа «концепция универсального вычислителя во времена Чарльза Бэббиджа, когда ещё не было ни радиоламп, ни транзисторов» — и ничего путного не придумывается, хотя и очень хочется. Ну, или концепция летательного аппарата тяжелее воздуха, когда ещё не было двигателей внутреннего сгорания, применённых братьями Райт в их самолёте. Но чаще идёт всё-таки analysis paralysis при абсолютно понятных вариантах синтеза: в любой момент эволюции существует огромное количество текущих квазиоптимальных решений конфликтов между системными уровнями (неустроенность/frustrations), и при этой неустроенности оказывается очень незначительный разброс характеристик при переходе от одного решения к другому. Эти характеристики могут быть достигнуты самыми разными способами, так что выбор среди похожих по характеристикам решений и впрямь труден, может идти бесконечное время, это и есть analysis paralysis. Конечно, хорошо бы предложить альтернативу из следующего поколения (изобретение, результат синтеза), дающую явное преимущество над другими альтернативами, чтобы выбор был очевиден, но это не всегда получается.
В какой-то момент вам надо будет пройти развилку при разработке концепции системы в ситуации, похожей на выбор между цифровым фотоаппаратом и плёночным: это легко в 1995 году и в 2005 году, но вот где-нибудь в 2000 году (Olympus CAMEDIA C1400L появилась в 1997 году53, матрица там была 1.41-megapixel) выбор был не очень очевиден. А теперь представьте себя на месте не потребителя, а производителя этих аппаратов! Kodak выбрал концепцию своих новых фотоаппаратов неправильно, и мы о нём уже редко слышим. Olympus выбрал концепцию правильно, фирма до сих пор существует (хотя и была продана в 2020 году, теперь это OM Digital Solutions54).
Неважно, кем делается выбор из множества альтернатив: коллегиально, визионерами, бизнесменами, инженерами (разработчиками или архитекторами как подроль разработчиков), или даже покупателями, которые выбирали из альтернативных предложений разных конкурентов в ходе проверки разных предпринимательских гипотез, высказанных и реализованных этими конкурентами. Главное, что есть три стадии, повторим их:
-
Нужно понимать, что вы делаете, какую функцию (метод работы) вам нужно реализовать, концепцию использования какой системы вы готовите. Если вы не сформулировали точно, чего хотите, вам не помогут потом лучшие методы изобретений: что-то вы изобретёте, но оно будет ненужным. Функциональная декомпозиция или функциональный синтез может осуществляться множеством способов, и вы легко можете захотеть невыполнимого. За то, чтобы не утерять связь с реальностью в этом вопросе, нужен исполняющий роль визионера (чаще всего он будет совмещать и роль менеджера, должность product manager): он проигнорирует «эксперименты ради экспериментов» и проконтролирует, чтобы состоялся business case, то есть проверит, что денег за систему с чудесными функциями заплатят больше, чем будет потрачено на её разработку и изготовление, включая окупаемость всех экспериментов и проверку неудачных гипотез.
-
Вы должны предложить несколько альтернативных концепций системы, их всегда больше одной, вариантов конструкции обычно много. Если оценивается только одна концепция, то вы что-то делаете не так. Если у вас один вариант для выбора, а не пять-шесть, то вы чего-то не понимаете в инженерии. Без этого не будет прохождения развилок, и это по факту будет не инженерия. Ситуация интересна ещё и тем, что какую-то из альтернативных предлагаемых концепций системы можно доработать так, что она будет предпочтительней. Этот шаг делается на базе самых разных вариантов методов генерации идей, «методов творчества».
-
Принятие решения, прохождение развилки между предложенными на предыдущей стадии альтернативными концепциями. Это делается на базе рациональности как фундаментального метода мышления: построение моделей и далее выбор между этими моделями, построение обоснований/rationale. Подробней об этом будет в разделе по инженерным обоснованиям, которые понимаются как обоснования успешности уже изготовленной системы на базе каких-то свидетельств и аргументации — assurance, так и обоснования выбора проектных функциональных или архитектурных/«важных для разработки и эксплуатации, но не связанных с предметной областью и функциональностью» решений.
И не факт, что прохождение этих стадий однократно. По ходу проекта понимание участников проекта улучшается, внешнее окружение изменяется, находятся новые нюансы в реализуемых функциях (методах работы), новые альтернативы конструкции, ошибки в принятии решений по выбору из альтернатив. Так что это не однократное прохождение стадий, а непрерывное уточнение концепции (и концепции использования, и концепции системы). А ещё после того, как вы вроде бы «всё уточнили, всё выбрали» для системы будут в ходе эволюционной разработки появляться всё новые и новые функции/фичи, для этого концепции системы (как вы понимаете, их много разных на разных системных уровнях — это мы называли «рекурсивным применением системного мышления», одинаковое мышление на разных системных уровнях) продолжают и продолжают уточняться.
Довольно много проблем в организации новых инженерных процессов происходит из-за попыток одновременного следования старым и новым методам работы:
-
Предлагается «монстрообразная методология», которую очень трудно освоить в полном объёме. Не предлагается собрать у себя инженерный процесс из подходящих методов, чтобы граф создания тоже эволюционировал в части используемых методов работы, всегда был SoTA. Мы касались этого в руководстве по методологии.
-
По инерции вписываются давно отброшенные в силу заведомой неработоспособности методы, например «теории уровней/ступеней зрелости/maturity». Когда-то модные в менеджменте «ступени зрелости» не прижились: компании довольно быстро проходили все эти ступеньки, но жизнь-то на этом не заканчивалась — эволюция продолжалась, а ступеньки это уже не описывали, получалась незапланированная стагнация: «цель достигнута, зрелость не поднимается, развитие закончили». Это упоминалось в руководствах по системному мышлению и методологии.
-
Делается заявление, что «у нас всё agile» — то есть «мы гибкие, быстрые, итеративные». Обсуждается «новомодный процесс» со старыми рабочими продуктами — agile, но не lean (например, остаются требования: итеративная ненужная работа, бесполезное проявление гибкости в ненужном. Мы подробно обсудили это в текущем разделе руководства).
-
… и такого много.
Скажем, берём «The Agile Systems Engineering Handbook»55 с многозначительным подзаголовком «This guide is a modern alternative to INCOSE, based on recent, proven experience inside fastest-moving engineering teams. Built in collaboration with the world's fastest teams, it’s designed to support high-speed, real-world engineering needs». Заглядываем — и видим тексты про уход от водопада, но также тексты про требования, тексты про ступени зрелости. Что с этим делать? Игнорировать? Совсем нет! Там ведь много интересного и полезного, это ведь отражение реального производственного опыта реальных «железных» инженеров — да ещё и с описанием культуры системной инженерии в SpaceX56. И там можно найти кроме инерционного использования понятий классической системной инженери, тех же требований, и следующие строки: At SpaceX, external-facing hard constraints requiring full V&V are still called requirements, used in interactions with entities like NASA/DoD. However, lower-level internal requirements aren't labeled as requirements; they're termed design criteria. Why the different terminology? It's all about psychology. Let's face it, "requirements" can carry negative connotations among engineers. The term implies rigid constraints that are seen as commandments that can’t be scrutinised or changed.
Надо просто использовать наставления нашего руководства, чтобы понимать там написанное, а особенно — понимать, что инженерный процесс для «железа» неминуемо начинает повторять инженерный процесс для софта, так что необязательно ждать много лет, пока «железные» инженеры воспримут эти новые идеи, можно пробовать что-то делать самостоятельно, работать на фронтире.
Моделирование: визионер, разработчик, эволюционный архитектор в моём проекте
Укажите агентов, которые выполняют роли визионера, разработчика и эволюционного архитектора в ваших трёх проектах (это могут быть подпроекты какого-то одного проекта). Оргроли могут исполнять не только отдельные люди (или сейчас даже AI), но и оргзвенья из нескольких агентов. Обратите внимание, что люди часто упускают себя в какой-то из этих ролей (пишут «никто», хотя сами являются, например, архитекторами — то есть принимают решения о том, что делать для достижения всяких «-остей»).
| Номер по порядку | Наименование проекта (по целевой системе) или подпроекта (по «нашей системе») | Исполнитель роли визионера | Исполнитель роли разработчика | Исполнитель роли эволюционного архитектора |
|---|---|---|---|---|
| 1. | ||||
| 2. | ||||
| 3. |
https://www.anandtech.com/show/21408/tsmc-roadmap-at-a-glance-n3x-n2p-a16-2025-2026, к этим «проектным нормам» нужно относиться с осторожностью, https://www.iguides.ru/main/other/sovremennye_tekhprotsessy_grandioznyy_obman_razbiraemsya_v_marketingovykh_tonkostyakh_protsessorov/
https://en.wikipedia.org/wiki/Cognitive_behavioral_therapy на базе behavior and cognitive psychology, https://www.apa.org/ed/graduate/specialize/behavioral-cognitive
См. про архитектурную оптимизацию в https://ailev.livejournal.com/1464563.html
https://www.diapazon-pharm.ru/kisecnorastvorimye-kapsuly-preimusestva-i-spros, https://patents.google.com/patent/RU2569742C1/ru
https://www.researchgate.net/publication/343999144_How_Formal_Requirements_Specifications_Inhibit_Creativity_in_Software_Engineering, и то же самое про шаблонизированные требования https://www.researchgate.net/publication/354528878_How_Templated_Requirements_Specifications_Inhibit_Creativity_in_Software_Engineering. Эта тема «иллюзии требований» разрабатывается с 2013 года, https://www.researchgate.net/publication/255831240_The_Illusion_of_Requirements_in_Software_Development