Начальный · Глава 1 / 18
Требование к устройству становится наблюдаемым договором
После главы: Превратить описание индикатора в входы, выходы, пределы и проверяемые сценарии.
В этой главе
Начинаем с поведения полки
Читатель нажимает кнопку и видит, достаточно ли света по условной шкале датчика. Это ещё не техническое требование. Слова «быстро», «достаточно» и «надёжно» позволяют двум разработчикам получить разные устройства. Для нашего учебного индикатора договоримся: кнопка переключает показ; отсчёт хранится вместе со временем; при отсутствии свежих данных включение запрещено; ошибка сохраняется до явного сброса после восстановления. Свет обозначается относительным уровнем, без заявления об измерении освещённости в физических единицах.
Теперь зададим границы. Модель принимает целые коды от нуля до 1023, двоичный уровень кнопки и целочисленное время в миллисекундах. На выходе получаем состояние OFF, ON или FAULT, ярлык уровня и диагностические счётчики. Это текстовая симуляция, а не электрическая схема. Отсутствие настоящего датчика позволяет повторить один сценарий много раз и понять причинность. Оно одновременно означает, что мы не испытали питание, помехи, нагрев, характеристики входов и физическую задержку вывода.
Разделяем запрет и пожелание
Инвариант должен выполняться при любом допустимом пути. Например, состояние FAULT никогда не включает декоративный выход. Сценарий описывает конкретную последовательность: получить хороший отсчёт, нажать кнопку, пропустить срок свежести. Пожелание вроде «красиво мигать» не заменяет ни того, ни другого. Запишите сначала важные инварианты, затем несколько сценариев, способных их нарушить. Такое разделение поможет позже увидеть, почему один успешный демонстрационный запуск не покрывает все способы отказа.
Пределы модели тоже являются требованиями. Очередь вмещает четыре команды; при переполнении новые команды отвергаются, счётчик потерь увеличивается, включается защёлкнутая ошибка. Срок свежести равен ста миллисекундам исключительно для короткой учебной трассы. Событие SENSOR_ERROR обрабатывается приоритетно, даже если очередь полна. Если отправить ошибку в тот же переполненный буфер, защита исчезнет именно при высокой нагрузке. Политика должна быть согласованной между формулировкой, кодом и ожидаемыми результатами.
Условия окружения нельзя спрятать
Предположим, основной цикл вызывается не реже раза в десять миллисекунд. Тогда проверка срока может опоздать относительно порога не более чем на этот промежуток в идеальной дискретной модели. Если вызовы остановились совсем, программная функция уже ничего не выключит. Эту границу нельзя исправить ещё одним условием внутри неработающей функции. На плате нужны подходящие аппаратные механизмы и отдельные требования к выходу; наш проект ограничен демонстрацией алгоритма при явных вызовах шага.
Такое условие следует записывать рядом с результатом испытания. Фраза «устаревшее значение отключено» означает, что после наступления срока был выполнен следующий шаг. Она не доказывает автоматическое отключение за заданное физическое время. В трассе сохраняйте плановый момент, фактический момент обработки и причину перехода. Позже вы сможете отличить неверный порог от задержки планировщика, а обе эти причины — от отсутствия новых измерений. Объяснимость начинается с точного определения наблюдения.
Приёмка до реализации
Для каждого правила подготовьте пример и контрпример. Валидный код 1023 принимается, код 1024 отвергается. Свежесть ровно сто миллисекунд допускается, сто одна — нет. Удержание кнопки создаёт одно событие, новое нажатие после принятого отпускания создаёт второе. После перезапуска не восстанавливаем право показывать прежний отсчёт. Эти маленькие границы важнее длинной случайной демонстрации, где неправильное поведение может ни разу не проявиться.
Документ договора остаётся коротким, но связанным с проверками. Если меняете вместимость очереди, исправляйте и сценарий переполнения. Если меняете смысл сброса, проверяйте ранний сброс и сброс после достаточного числа новых отсчётов. Не расширяйте обещания проекта вслед за каждым новым термином: знание слова watchdog ещё не делает симулятор промышленным контроллером. Результатом этой главы является проверяемая задача, достаточно узкая для законченного решения и достаточно содержательная, чтобы показать взаимодействие ограничений.
Разобранный пример
Матрица границ до кода
В модели используется обычный целочисленный возраст. Таблица проверяет выбранный договор включительно по правой границе; физическое течение времени здесь не измеряется.
pythondef fresh(age, limit=100):
return type(age) is int and 0 <= age <= limit
cases = [(-1, False), (0, True), (100, True),
(101, False), (True, False)]
for age, expected in cases:
assert fresh(age) is expectedТеперь самостоятельно
Практика
Составьте приёмку для команды RESET: ошибка возникла, затем пришло два хороших отсчёта, оператор запросил сброс, пришёл третий отсчёт, оператор повторил запрос. Договор требует три новых хороших отсчёта подряд.
Результат: Пять шагов со состояниями и объяснение, почему прежний хороший отсчёт до ошибки не считается.
Подсказка
- Отсчитывайте подтверждения восстановления после последней причины ошибки.
Решение и проверка
После ошибки состояние FAULT, после первого и второго отсчётов оно сохраняется. Первый RESET оставляет FAULT. Третий отсчёт разрешает восстановление, но сам ничего не сбрасывает; повторный RESET переводит в OFF. Автоматического включения нет.
Старое измерение предшествовало отказу и не подтверждает нынешнюю работоспособность. Если между вторым и третьим отсчётом возникнет новая ошибка, серия начинается заново. Такой сценарий проверяет смысл слова «подряд», а не только достижение численного счётчика.
Проверьте себя без текста
Чем инвариант отличается от сценария?
Инвариант обязателен для всех допустимых путей, сценарий проверяет одну определённую последовательность.
Что может доказать вызов функции свежести?
Только решение на переданных данных; соблюдение физического срока требует работы окружения и отдельного измерения.
Проверить по первоисточникам
Конец образца
Полный том содержит 18 глав, решения, итоговый проект и словарь. Продажи откроются после предметной редактуры и подключения магазина.