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

на главную - закладки

Жанры

Искусство программирования для Unix

Реймонд Эрик Стивен

Шрифт:

В действительности, философия MIT и Нью-Джерси имеет аналоги как конфликтующие направления в самой Unix-традиции проектирования. Один тип Unix-мышления придает особое значение небольшим точным инструментам, конструкциям, разработанным с нуля, а также простым и последовательным интерфейсам. Дуг Макилрой решительно отстаивает данную точку зрения. Другой тип мышления акцентирует внимание на простых реализациях, которые работают и быстро распространяются, даже если используются методы грубой силы, а некоторые граничные случаи необходимо устранить. Код Кена Томпсона, а также его принципы программирования часто и очевидно склоняются к этому направлению.

Конфликт между данными подходами возникает именно потому, что иногда программист может получить простой интерфейс, если согласен

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

На практике применяются оба подхода. Unix-разработчики старой школы немедленно подумают о сравнении System V и BSD-стилей обработки программных сигналов. Последний следует MIT-философии, тогда как System V-стиль происходит из Нью-Джерси. В основе выбора между ними лежит сложный вопрос, который непосредственно не касается распространения программного обеспечения: если цель заключается в ограничении глобальной сложности, что разработчик охотнее всего принесет в жертву? Что ему следует принести в жертву?

Одним эпохальным примером, не упомянутым Гэбриэлом, являются распределенные гипертекстовые системы. Ранние проекты распределенных гипертекстовых систем, такие как NLS и Xanadu, были жестко ограничены предположениями MIT-философии о том, что ссылки, указывающие на несуществующий объект, являются недопустимой неполадкой в пользовательском интерфейсе. Это ограничивало системы либо просмотром только контролируемого, закрытого набора документов (как, например, на одном CD-ROM), либо реализацией различного тиражирования со все возрастающей сложностью, кэширующих и индексирующих методов в попытке предотвратить случайное исчезновение документов. Тим Бернерс-Ли (Tim Berners-Lee) разрубил этот гордиев узел, разрешив проблему в классическом стиле Нью-Джерси. Простота реализации, достигнутая им благодаря разрешению ответа "404: Not Found", была тем, что сделало систему World Wide Web достаточно легковесной, чтобы она могла успешно распространяться.

Сам Гэбриэл придерживался мнения о том, что "худшее" более заразительно и, в конце концов, стремится к победе. Несмотря на это, он неоднократно публично менял свое мнение относительно основополагающего вопроса, связанного со сложностью: сложность — это хорошо или плохо? Его непостоянство отражает множество продолжающихся споров в Unix-сообществе.

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

13.1.3. Необходимая, необязательная и случайная сложность

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

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

Реактивные самолеты обладают необходимой сложностью. Существует довольно четкая грань, за которой невозможно принести в жертву функции в обмен на простоту, поскольку самолет должен оставаться в воздухе. Благодаря самому этому факту, разработчики авиационных электронных систем управления не склонны втягиваться в "религиозные войны" в вопросе сложности, Unix-программисты также часто избегают их.

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

Для того чтобы добиться более яркого видения проблемы, необходимо начать с определения отличия между случайной сложностью и необязательной сложностью [111] . Случайная сложность возникает вследствие того, что разработчик не нашел простейшего способа реализации заданного набора функций. Такая сложность преодолевается благодаря хорошему проектированию или хорошему перепроектированию. С другой стороны, необязательная сложность связана с некоторой желаемой функцией. Необязательная сложность может быть устранена только путем изменения целей проекта.

111

Разделение случайной и необязательной сложности означает, что рассматриваемые здесь категории не являются тем же, что сущность и случайность в очерке Фреда Брукса "No Silver Bullet" [8], однако в философском смысле они имеют одинаковое происхождение.

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

13.1.4. Диаграмма видов сложности

Выше были показаны две различные шкалы для анализа сложности. Данные шкалы фактически перпендикулярны друг другу. Рис. 13.1 может помочь при выяснении связей. В каждом из девяти блоков на рисунке приведен общий источник определенного вида сложности.

Рис. 13.1. Источники и виды сложности

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

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

Курсант: назад в СССР

Дамиров Рафаэль
1. Курсант
Фантастика:
попаданцы
альтернативная история
7.33
рейтинг книги
Курсант: назад в СССР

Чужая семья генерала драконов

Лунёва Мария
6. Генералы драконов
Фантастика:
фэнтези
5.00
рейтинг книги
Чужая семья генерала драконов

Пышка и Герцог

Ордина Ирина
Фантастика:
юмористическое фэнтези
историческое фэнтези
фэнтези
5.00
рейтинг книги
Пышка и Герцог

Имперский Курьер. Том 5

Бо Вова
5. Запечатанный мир
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Имперский Курьер. Том 5

Имя нам Легион. Том 7

Дорничев Дмитрий
7. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 7

Возвышение Меркурия

Кронос Александр
1. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия

Законы Рода. Том 11

Андрей Мельник
11. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 11

Измена. (Не)любимая жена олигарха

Лаванда Марго
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. (Не)любимая жена олигарха

Вираж бытия

Ланцов Михаил Алексеевич
1. Фрунзе
Фантастика:
героическая фантастика
попаданцы
альтернативная история
6.86
рейтинг книги
Вираж бытия

Отмороженный 11.0

Гарцевич Евгений Александрович
11. Отмороженный
Фантастика:
боевая фантастика
рпг
попаданцы
фантастика: прочее
фэнтези
5.00
рейтинг книги
Отмороженный 11.0

История "не"мощной графини

Зимина Юлия
1. Истории неунывающих попаданок
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
История немощной графини

Крестоносец

Ланцов Михаил Алексеевич
7. Помещик
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Крестоносец

Газлайтер. Том 15

Володин Григорий Григорьевич
15. История Телепата
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Газлайтер. Том 15

Призыватель нулевого ранга

Дубов Дмитрий
1. Эпоха Гардара
Фантастика:
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Призыватель нулевого ранга