- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
The Programmers Stone (Программистский камень) - Alan Carter
Шрифт:
Интервал:
Закладка:
Пакетная. Хотя их часто считают устаревшей стратегией с использованием перфокарт, пакетные системы просты, надежны, великолепно себя ведут при неустойчивой связи и масштабируются лучше, чем интерактивные системы.
Управляемая событиями. Реагирует на события из внешнего мира. Приложения с графическим интерфейсом большую часть времени находятся в ожидании, пока пользователь что-нибудь нажмет, чтобы отреагировать на событие. «Однорукие бандиты» (игровые автоматы) — тоже управляемые событиями системы, как и сигнализация. У управляемых событиями систем сложное пространство состояний и большая чувствительность к вводимым данным. Часто для них ограничивается время ответа на событие. Если проблему можно представить как не управляемую событиями систему, то лучше так и сделать.
Управляемая данными. Аналогична управляемой событиями и пакетной, но с ясными потоками данных через каждую подсистему, где наличие входных данных — это событие-триггер, заставляющее каждую подсистему выполнять свой цикл обработки. Управляемые данными системы гибче пакетных, поскольку размер пакета может изменяться динамически, но они обладают надежностью пакетных систем, поскольку мы всегда можем узнать, как далеко мы зашли в обработке каждого пакета. Каждая подсистема может организовывать элементарную операцию, выдающую информацию и удаляющую входные данные, так что даже при восстановлении после сбоя питания система сразу готова к работе, поскольку состояние системы всегда устойчиво. Системы электронной почты — пример систем, управляемых данными.
Оппортунистическая. (рассчитывающая на благоприятную возможность)Этот тип систем никогда не пострадает от ошибок при передаче, поскольку они используют каналы только тогда, когда это возможно. В действительности, большинство офисов оппортунистические, поскольку они построены на основе Ethernet. Данные хранятся в буфере до тех пор, пока локальный передатчик не передаст их без конфликтов (collision).
Штурманская (Dead reckoning). Пытается проследить каждый шаг пользователя. Часто представляется желательной, поскольку позволяет обеспечить сильную проверку данных пользователя, но может оказаться очень хрупкой, что приводит к шуткам типа знаменитой: «Бесполезно нажимать на это, компьютер говорит, что этого тут нет!»
Сходящаяся в одну точку (Convergent). Тут не интересно отслеживать каждый шаг происходящего в реальном мире процесса, здесь внимание направлено на регистрацию изменений состояний в ключевых точках и интегрировании данных в виде аккуратной картины реального мира в некоторый момент в прошлом, и прогрессивно ухудшающейся аппроксимацией по мере приближения к настоящему. Мобильные пользователи, которые закачивают данные со своих ноутбуков в корпоративную сеть — хороший пример. Мы очень точно знаем, как много мы продали на прошлой неделе, очень приблизительно знаем о вчерашнем дне, но мы не получили еще данные от Джона и Джилла, поэтому не знаем почти ничего о сегодняшнем дне.
На гребне волны (Wavefront). Системы, работающие по мере появления событий. Управление освещением или телефонная коммутация — вот примеры. При сбоях мы больше заинтересованы в быстром восстановлении работы, чем обеспокоены потерей данных.
Ретроспективная (Retrospective). Связанная с поддержанием аккуратной записи прошлого. Избежание потерь данных обычно очень важно. Пример — бухгалтерские системы.
Обработка ошибок — лимфатическая система программы
Часто говорят, что следует перехватывать сообщения об ошибках, но в этом мало пользы, если неизвестно, что же с ними собираются делать. Обработка ошибок составляет такую же часть структуры программы, как и логика обработки нормальных ситуаций, но не настолько же почитаема. Эта связь скорее похожа на взаимодействие кровеносной и лимфатической систем в теле. Вам необходимо предусматривать обработку ошибок на каждой стадии проектирования. Например, нет никакого смысла регистрировать сообщения об ошибках записи в журнал ошибок в процедуре обработки ошибок!
Концептуальная целостность требует, чтобы вы определили общий подход к обработке ошибок, используемый по всему проекту. Как вы будете сообщать об ошибках? Какие идиомы будут применять программисты для элегантной проверки ошибок без нарушения главного потока управления? Совершенно необязательно делать второй вызов, чтобы проверить, возникла ли ошибка или что там было — иначе код будет распухать. В идеале ошибки должны проверяться при выходе из функции, чтобы использовать краткие идиомы, что приводит к получению понятного кода и, как следствие, плато качества:
if((fp = fopen(…)) == NULL) { // Error }
или
if(!DoTheBusiness()) { // Error }
Можно слышать множество жалоб на распухание логики обработки ошибок до состояния, когда строго написанный вызов функции может занимать столько строк, что уже невозможно увидеть всю картину в целом. Как картостроители, мы знаем, что обрастание таким количеством Достойных стандартов кодирования, что невозможно написать замечательную программу — ошибочный путь.
В процедурном (и, в некоторой степени, объектном) подходе к коду ведется дискуссия по поводу стратегии обработки ошибок, где их следует обрабатывать. В дискуссии рассматриваются два подхода. Первый говорит, что вызываемая подпрограмма не должна возвращать управление, пока она не выполнила то, что ее просили, и это можно назвать «полным делегированием». Другой говорит, что вызываемая подпрограмма должна выполняться, пока не столкнется с проблемой, и тогда аккуратно возвращать наверх весь мусор, который она получила и сообщать вызывавшему, что произошла ошибка — это мы назовем «ложная готовность».
Привлекательность полного делегирования состоит в том, что при этом получается очень чистый код с вызывающей стороны, и он может быть очень эффективным, и он препоручает ответственность за поддержание состояния более низких уровней самим уровням. Недостаток заключается в том, что он работает только при условии, что вызывающей стороне на самом деле не требуется обработка последствий ошибки в ее собственном контексте. Это ограничивает его системами для типовых ситуаций, где приложение действительно может не знать о том, что происходит на нижних уровнях, и если нижний уровень реально не сможет устранить проблему, то попытка возврата будет недопустима, поскольку приведет либо к зависанию процесса либо к фатальной ошибке.
Ложная готовность всегда позволяет вызывающей стороне отреагировать на проблемы, и вложенные вызовы смогут откатить стек, пока не будет достигнут уровень, способный разобраться с проблемой. Логика обработки ошибок пронизывает каждый уровень, но может быть минимизирована аккуратным кодированием, если автор и сопровождающий знают, как работать в этой схеме. Кроме того, можно обеспечить трассировку вызовов, показывающую, как процесс напоролся на проблему, так что всегда можно воспроизвести ситуацию.
Мы не думаем, что нужно дискутировать на эту тему, поскольку когда полное делегирование применимо, оно оказывается на самом нижнем уровне. Смешивание этих подходов приводит к кошмару в коде, поскольку нарушает концептуальную целостность.
Некоторые объектные языки предоставляют исключения, которые позволяют автоматически схлопывать стек до уровня, ответственного за обработку данной ошибки. Это замечательный способ освободить основную логику от деталей обработки ошибок. Важный момент, который нужно помнить, заключается в том, что иногда исключение может быть передано гораздо выше, если ты хочешь не просто обработать его, а хочешь знать, из-за чего оно произошло. Сообщение об ошибке с нижнего уровня, говорящее
Could not write() datafile ftell() = 246810
если за ним не следует другое, говорящее
Could not Save World
при отладке просто бесполезно. Ты можешь передавать исключения на более высокий уровень без нарушения главной логики управления, и следует подумать, как это сделать.
Не злоупотребляй в рабочее время исключениями для создания замысловатого потока управления. В особенности не скрывай longjmp() в макросах и не вызывай их из обработчиков. Если ты желаешь поэкспериментировать с Силами Тьмы, делай это дома. Нам всем приходится это делать, но что печальнее всего, и наши коллеги могут ухватиться за неправильную идею и начнут ее рационализировать. Не кажется ли странным, что мы производим сегодня языки, которые страдают запорами по этому поводу, когда заняло годы просто правильно переопределить с помощью const описания прототипов функций, но при этом нам позволено фокусничать с потоком управления так, как мы не пытались делать даже на ассемблере?
По возможности избегайте расставлять захламляющие ваш код assert()и условную компиляцию отладочных макросов. Вам не достичь необходимой достаточности плато качества, если все вокруг завалено мусором.

