2.12

Смотреть на английском

2.12 Модели и методы разработки программ

Обзор и мотивация

Программная модель это намеренное упрощение системы, построенное, чтобы ответить на конкретный вопрос. Метод это дисциплинированный способ создания программ, включая модели, которые он использует по пути. Вместе они образуют область знаний свода знаний по программной инженерии (SWEBOK), потому что это умственные инструменты, которыми вы рассуждаете о системе до, во время и после её построения. Диаграмма классов UML (унифицированного языка моделирования), диаграмма «сущность-связь» (ERD), конечный автомат, формальная спецификация и одноразовый прототип все являются моделями. Водопад, прототипирование, формальная разработка и гибкие методы все являются методами.

Зачем вообще нужны модели? Потому что рабочая память человека мала, а программные системы велики. Никто не может держать в голове систему из ста тысяч строк, поэтому мы рисуем картинки и пишем абстракции, показывающие по одной грани за раз: данные, поток управления, состояния, взаимодействия. Модель никогда не призвана быть верной коду; она призвана быть пригодной для решения. Хорошая модель показывает именно то, что нужно, чтобы что-то решить, и скрывает всё остальное.

В больших командах настоящие ставки это координация и коммуникация. Когда сотни инженеров, архитекторов, аналитиков и аудиторов работают над одной системой, общие модели это общая почва, на которой они договариваются о проекте, требованиях и рисках. Поэтому воспринимайте моделирование как инструмент с работой, которую нужно сделать. Оно окупается, когда модель дешевле предотвращаемой ею ошибки. Оно становится потерей, когда вы рисуете её ради неё самой, храните давно устаревшей или прорабатываете дальше решения, которому она должна была служить. Моделирование тесно связано с требованиями к программному обеспечению (глава 2.8), принципами проектирования программ (глава 2.2), архитектурой и её нотациями вроде C4 и arc42 (глава 3.1) и гибкими способами работы (глава 10.7).

Ключевые принципы

  • У каждой модели есть цель; если вы не можете назвать решение, которое она информирует, не рисуйте её.
  • Абстракция основное действие моделирования: включайте то, что важно для цели, опускайте остальное.
  • Согласованность важна внутри моделей и между ними; противоречивые модели хуже отсутствующих.
  • Модели сначала артефакты коммуникации; их аудитория определяет нотацию и детализацию.
  • Предпочитайте самую лёгкую модель, отвечающую на вопрос; проработка имеет стоимость содержания.
  • Модель хороша настолько, насколько хорош её анализ; непроверенная модель это нетестированное допущение.
  • Выбирайте метод под неопределённость, риск и последствия отказа проблемы.

Рекомендации

Моделируйте с абстракцией, целью и согласованностью

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

Выбирайте структурные или поведенческие модели под вопрос

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

Анализируйте модели, а не только рисуйте их

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

Применяйте эвристические методы по умолчанию

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

Резервируйте формальные методы для высокозначимых ядер

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

Используйте прототипирование, чтобы устранять неопределённость

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

Подбирайте метод под риск, а не под моду

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

Компромиссы: плюсы и минусы

Модель или методПри хорошем примененииРежим отказа
Структурные модели (UML, ERD)Общая картина частей и данныхРасползание диаграмм; дрейф от кода
Поведенческие модели (состояния, последовательности, активности)Раскрывают время, состояния и крайние случаиЧрезмерно детальные диаграммы, которые никто не читает
Эвристические методыБыстро, гибко, подходят большинству системНедисциплинированность; скрытые допущения
Формальные методыДоказуемые свойства для критических ядерВысокая стоимость; неверное применение ко всей системе
ПрототипированиеДешёвое обучение; рано устраняет рискОдноразовый код, повышенный до эксплуатации
Гибкие методыАдаптация к меняющимся требованиямПропускают моделирование, нужное для трудных задач

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

Вопросы для обсуждения с командой

  1. Анализируем ли мы наши модели или просто рисуем и идём дальше? Модель оправдывает своё существование анализом, а не существованием: конечный автомат, который вы никогда не проверяете на недостижимые состояния или отсутствующие переходы, это нетестированное допущение, наряженное в диаграмму. В большой команде именно здесь прячутся настоящие дефекты, потому что правдоподобно выглядящей картинке доверяют именно тогда, когда никто не прошёл её относительно требований, чтобы найти отсутствующий путь ошибки или осиротевшую связь. Принесите на встречу вашу самую важную поведенческую модель и попробуйте её сломать: какой переход не определён, у какого состояния нет выхода, в какой последовательности нет тайм-аута? Там, где стоимость отказа высока, ответ должен подтолкнуть вас к анализу с поддержкой инструментов (проверка моделей, проверка согласованности, симуляция), а не разглядыванию на глаз, потому что весь смысл моделирования критического ядра в том, чтобы найти изъян на доске, а не в эксплуатации.

  2. Когда две наши модели расходятся, какая побеждает и кто замечает противоречие? Согласованность важна внутри моделей и между ними, а противоречивые модели хуже отсутствующих, потому что люди действуют по обеим. В большой системе сущности в модели данных, классы в проекте и существительные в требованиях тихо расходятся, пока разные команды обновляют разные артефакты, и первый признак часто ошибка в эксплуатации, когда два компонента разошлись в представлении о том, что такое вещь. Принесите пример: выберите основное понятие и проверьте, согласуются ли ERD, код и требования в его форме и жизненном цикле. Если нет, решите, какой артефакт авторитетен и кто отвечает за приведение остальных в соответствие, и будьте готовы удалить модель, а не позволять устаревшей продолжать лгать команде.

  3. Какое ядро в нашей системе, если оно неверно, теряет реальные деньги или вредит кому-то и получает ли оно заслуженную строгость? Центральный ход этой главы подбор метода под риск: эвристические и гибкие методы для исправимого большинства, формальная спецификация и верификация для малого высокозначимого ядра и дешёвое прототипирование для действительно неопределённого. Режимы отказа симметричны и оба дороги: применение формальных методов к маркетинговому микросайту сжигает деньги, а воспринимание движка расчётов или набора правил права как обычной гибкой работы приглашает катастрофический необратимый дефект. Принесите карту вашей системы и отметьте, где ошибка катастрофична, а где исправима и где требования определены, а где неизвестны. Ответ должен сконцентрировать ваши вложения в моделирование там, где деньги и неоднозначность, и явно удержать их везде остальное, чтобы критическое формальное ядро могло сидеть внутри в остальном гибкой оболочки, не затекая в чужую территорию.

  4. Сколько моделирования мы делаем до написания кода и меняется ли эта доза с неопределённостью перед нами? Большой предварительный проект и полное отсутствие проекта оба режимы отказа, а правильная доза лежит между ними и определяется тем, сколько неопределённости модель на самом деле устраняет. В большой команде давление идёт в обе стороны: процесс управления может требовать полного набора диаграмм до любого кода, фиксируя решения, принятые при наименьшей информации, тогда как давление поставки может толкать команду пропустить тот единственный конечный автомат, который поймал бы дорогой крайний случай. Принесите ваши два последних проекта и разделите созданные модели на информировавшие реальное решение и нарисованные только потому, что шаблон их требовал. В корпоративных и государственных программах, где фазовый шлюз или совет по утверждению часто предписывает документы заранее, придите готовыми отстаивать моделирование, следующее за риском, а не фиксированным списком результатов, чтобы платёжное ядро получило строгость, а внутренний инструмент отчётности не утонул в диаграммах, которые никто не читает.

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

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

Взгляд по секторам

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

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

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

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

Примеры

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

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

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

Бизнес-обоснование: мотивы, ROI и TCO

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

Затраты реальны, и их нужно взвешивать. Модели требуют времени на построение, навыков для хорошего построения и постоянных усилий для поддержания актуальности; формальные методы добавляют труд специалистов. Точка безубыточности определяется неопределённостью и последствиями. Где оба низки, тяжёлое моделирование разрушает ценность и побеждают гибкие эвристики. Где что-то одно высоко, целевое моделирование и, для критического ядра, формальная верификация окупаются многократно, предотвращая дорогой класс отказа. Чтобы обосновать руководству, свяжите вложения в моделирование с конкретными устранёнными рисками и сопровождаемостью долгоживущих систем. И отслеживайте, действительно ли к моделям обращаются, потому что неиспользуемая модель чистая стоимость.

Антипаттерны и ловушки

  • Моделирование ради моделирования: создание диаграмм, потому что процесс требует, а не потому что они информируют решение.
  • Устаревшие модели, которым верят как истине: диаграммы, больше не соответствующие коду, но всё ещё используемые.
  • Большой предварительный проект: исчерпывающие модели до любого кода, фиксирующие решения, принятые при наименьшей информации.
  • Расползание диаграмм: все типы UML применяются единообразно, топя немногие полезные представления в шуме.
  • Формальные методы везде: применение дорогой верификации к коду, где последствия отказа этого не оправдывают.
  • Случайное повышение прототипа: одноразовый прототип, тихо выпущенный как продукт.
  • Нотация вместо сути: споры о корректности UML вместо того, отвечает ли модель на вопрос.

Модель зрелости

  • Уровень 1 (Начальный): Моделирование стихийно или отсутствует и чисто реактивно; метод не назван; модели, если вообще рисуются, непоследовательны, не анализируются и заброшены, как только заканчивается встреча.
  • Уровень 2 (Развитие): Некоторые команды рисуют распространённые диаграммы и следуют названному методу, но практика неравномерна по организации: модели часто создаются церемониально, дрейфуют от кода и редко анализируются на дефекты.
  • Уровень 3 (Стандартизация): Общая нотация, документированное руководство по выбору метода и правила согласованности определены и соблюдаются по всей организации; модели выбираются по цели, поддерживаются в соответствии с системой, рецензируются на дефекты, а метод подбирается под риск каждой проблемы.
  • Уровень 4 (Управление): Моделирование измеряется и контролируется относительно базовых значений; команды отслеживают, сколько дефектов анализ ловит до реализации, насколько модели дрейфуют от кода, обращались ли к каждой модели для реального решения и какие переделки и время цикла сэкономлены относительно определённой базы; выбор метода калибруется по измеренной неопределённости и последствиям, а критические ядра формально верифицируются по согласованным целям охвата.
  • Уровень 5 (Оркестрация): Моделирование и выбор метода непрерывно улучшаются и интегрированы с планированием поставки и рисков по организации; вложения адаптируются по мере смещения неопределённости и последствий, модели регулярно поддерживаются актуальными, выводятся или углубляются на основании свидетельств, а формальные, эвристические методы и прототипирование комбинируются так, что каждый стоит ровно там, где окупается.

Идеи для обсуждения

  • В вашем последнем проекте какие модели информировали реальное решение, а какие были нарисованы только потому, что процесс требовал?
  • Где в ваших системах формальная спецификация окупилась бы, а где была бы потерей?
  • Как вы решаете, одноразовый прототип или эволюционный, и обеспечиваете ли это решение?
  • Как вы не даёте моделям расходиться с кодом или принимаете, что некоторые лучше удалить?
  • Какое количество моделирования до кода правильно в вашем контексте и как оно меняется с неопределённостью?
  • Какая поведенческая модель (состояний, последовательности или активности) поймала бы ваш самый недавний инцидент в эксплуатации?

Главные выводы

  • Модель это целенаправленная абстракция; если вы не можете назвать решение, которое она информирует, не рисуйте её.
  • Подбирайте структурные и поведенческие модели под конкретный вопрос и держите их согласованными и актуальными.
  • Анализируйте модели; непроверенная модель это нетестированное допущение.
  • Эвристические и гибкие методы подходят большинству систем; формальные методы резервируйте для высокозначимых ядер.
  • Используйте прототипы для устранения неопределённости и заранее решайте, одноразовые они или эволюционные.
  • Вкладывайтесь в моделирование пропорционально неопределённости, которую оно устраняет, и цене ошибки в решении.

Источники и дополнительное чтение

  • IEEE Computer Society, SWEBOK Guide (Software Engineering Body of Knowledge), Version 4.0, Software Engineering Models and Methods knowledge area
  • Martin Fowler, UML Distilled: A Brief Guide to the Standard Object Modelling Language
  • Grady Booch, James Rumbaugh, Ivar Jacobson, The Unified Modelling Language User Guide
  • Frederick P. Brooks, The Mythical Man-Month and No Silver Bullet: Essence and Accident in Software Engineering
  • Daniel Jackson, Software Abstractions: Logic, Language, and Analysis (the Alloy modelling language)
  • Leslie Lamport, Specifying Systems (TLA+)
  • Simon Brown, Software Architecture for Developers (the C4 model)
  • David Harel, Statecharts: A Visual Formalism for Complex Systems