Чтение онлайн

на главную

Жанры

The Programmers' Stone (Программистский камень)
Шрифт:

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

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

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

Could not write datafile ftell = 246810

если за ним не следует другое, говорящее

Could not Save World

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

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

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

Увлечение формой (а не содержанием) и комбинаторный взрыв

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

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

Современная легенда в ICL гласит, что когда они покупали первую партию плат от Fujitsu, то сделали оценку, что надежность будет составлять 1% отказов. Поэтому прямо перед отправкой первой сотни один из директоров Fujitsu взял сверху из ящика плату и, перед тем как положить ее обратно, стукнул по ней молотком.

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

Сначала мы находимся в нормальном режиме. Затем попадаем в режим сбоя. Затем в режим восстановления. Что случится, если опять произойдет сбой? Что, у нас приключился сбой во время восстановления из режима сбоя? Восстановления из сбоя во время восстановления из сбоя? Тут очень легко появляется необходимость бесконечного расползания системы режимов, а не просто распознавание сбоев. Конечно, если дизайн всех уровней одинаков, то ничего страшного -- вам остается лишь доказать, что это именно тот случай.

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

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

Избегайте избыточности представления

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

Дело в том, что концепция нормализации базы данных из тех же соображений применима везде. Никогда не храните одну вещь и, отдельно, еще одну неподсоединенную вещь, которая полагается на то, что первая существует. Пусть данные управляют своей собственной структурой, и не появится никаких перекосов. Ритуальное использование структур данных часто включает претензию на управление держа зубную щетку и палочки для еды в одной руке. Если мы создаем структуру финансовых отчетов в Ящике А, а сложное описание Ящика А в Ящике В, то мы можем провести много времени копаясь в Ящике В, и ни разу не обратим внимания на тот факт, что на самом деле мы вообще не понимаем того, что происходит в Ящике А!

Поделиться:
Популярные книги

Кодекс Охотника. Книга XXII

Винокуров Юрий
22. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXII

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9

Кодекс Охотника. Книга XXXIII

Винокуров Юрий
33. Кодекс Охотника
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Кодекс Охотника. Книга XXXIII

Сержант. Назад в СССР. Книга 4

Гаусс Максим
4. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сержант. Назад в СССР. Книга 4

На границе империй. Том 10. Часть 6

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 6

"Новый Михаил-Империя Единства". Компиляцияя. Книги 1-17

Марков-Бабкин Владимир
Избранные циклы фантастических романов
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Новый Михаил-Империя Единства. Компиляцияя. Книги 1-17

Законник Российской Империи. Том 3

Ткачев Андрей Юрьевич
3. Словом и делом
Фантастика:
городское фэнтези
альтернативная история
аниме
дорама
5.00
рейтинг книги
Законник Российской Империи. Том 3

Аристократ из прошлого тысячелетия

Еслер Андрей
3. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Аристократ из прошлого тысячелетия

Фиктивный брак

Завгородняя Анна Александровна
Фантастика:
фэнтези
6.71
рейтинг книги
Фиктивный брак

Убивать, чтобы жить

Бор Жорж
1. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать, чтобы жить

На границе империй. Том 10. Часть 2

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
5.00
рейтинг книги
На границе империй. Том 10. Часть 2

Неудержимый. Книга XXI

Боярский Андрей
21. Неудержимый
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Неудержимый. Книга XXI

Искатель 7

Шиленко Сергей
7. Валинор
Фантастика:
рпг
фэнтези
попаданцы
гаремник
5.00
рейтинг книги
Искатель 7

Я все еще граф. Книга IX

Дрейк Сириус
9. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я все еще граф. Книга IX