Искусство программирования для Unix - Эрик Реймонд
Шрифт:
Интервал:
Закладка:
Традиция IETF усилила этот инстинкт, научив нас считать код вторичным по отношению к стандартам. Стандарты являются тем, что позволяет программам взаимодействовать; они связывают технологии в единое целое. Опыт IETF показывает, что тщательная разработка стандартов, стремящаяся к сбору лучшего из существующей практики, является той формой сдержанности, которая достигает гораздо большего, чем претенциозные попытки переделать мир по образу нереализуемого идеала.
После 1980 года влияние данного урока стало более заметно в Unix-сообществе. Поэтому, несмотря на то, что стандарт ANSI/ISO С 1989 года не был абсолютно безупречным, он был исключительно четким и практичным для стандарта такого размера и важности. Единая спецификация Unix содержит "атавизмы" трех десятилетий экспериментов и фальстартов в более сложной области и, следовательно, является более беспорядочной, чем ANSI С. Однако компонентные стандарты, из которых она собрана, весьма хороши; твердым доказательством этого является тот факт, что, читая ее, Линус Торвальдс успешно создал Unix с нуля. Скромный, но мощный пример IETF создал один из критически важных блоков среды, которая сделала возможным подвиг Торвальдса.
Уважение к опубликованным стандартам и процессу IETF глубоко проникло в Unix-культуру. Умышленное нарушение Internet STD-стандартов просто невыполнимо. Это может иногда создавать пропасть взаимного непонимания между людьми с Unix-опытом и другими, склонными предполагать, что наиболее популярная или широко распространенная реализация протокола по определению является верной — даже если она нарушает стандарт так жестко, что не способна взаимодействовать с тщательно согласованным программным обеспечением.
Для Unix-программиста характерно уважение к опубликованным стандартам, поэтому он, скорее всего, будет враждебно относиться к спецификациям других видов. К тому времени, когда "водопадная модель" (исчерпывающая спецификация, затем реализация, затем отладка без возврата к любой стадии) утратила популярность в литературе по программной инженерии, она уже в течение многих лет была предметом насмешек среди Unix-программистов. Опыт и сильная традиция совместной разработки уже научили их, что лучший способ заключается в создании прототипов и повторных циклах тестирования и развития.
Традиция Unix четко определяет, что спецификации могут иметь большую ценность, но требует, чтобы они интерпретировались как временные и постоянно пересматривались в процессе практического использования так же, как пересматриваются стандарты Internet-Drafts и Proposed Standards. В лучшей практике Unix документация на программу используется как спецификация, подлежащая пересмотру, аналогично предложенному стандарту Internet.
В отличие от других сред, в Unix-разработке документация часто пишется до программы или, по крайней мере, совместно с ней. Для X11 основные стандарты X были закончены до выхода первой версии системы X и с тех пор остались по существу неизменными. Совместимость между различными Х-системами совершенствуется далее путем скрупулезного тестирования, управляемого спецификацией.
Наличие хорошо написанной спецификации значительно упростило разработку тестового комплекта для системы X. Каждое положение в X-спецификации было преобразовано в код для проверки реализации. В ходе данного процесса в спецификации было обнаружено несколько незначительных несоответствий, но результатом является тестовый комплект, который охватывает значительную часть кодовых путей внутри пробной X-библиотеки и сервера, и ни один из них не ссылается на исходный код данной реализации.
Кит Паккард.Частичная автоматизация создания тестовых комплектов обоснованно считается главным преимуществом. Практический опыт и достижения в области графического искусства побудили многих критиковать систему X относительно конструкции, а различные ее части (такие как безопасность и модели пользовательских ресурсов) кажутся неповоротливыми и слишком усложненными. Но несмотря на это реализация X достигла выдающегося уровня стабильности и совместимости систем, создаваемых различными поставщиками.
В главе 9 обсуждалось значение переноса программирования на как можно более высокий уровень в целях минимизации влияния постоянной плотности ошибок. Цитата Кита Паккарда скрывает в себе идею о том, что документация системы X представляет собой не просто перечень пожеланий, а некоторую форму высокоуровневого кода. Другой ведущий разработчик X подтверждает это мнение.
В X-системах спецификация всегда превалировала. Иногда спецификации содержат ошибки, которые также необходимо исправлять, но обычно ошибки встречаются чаще в коде, чем в спецификации (во всяком случае, это характерно для любой стоящей спецификации).
Джим Геттис.Далее Джим отмечает, что процесс развития X фактически весьма похож на процесс IETF. Его польза не ограничивается конструированием хороших тестовых комплектов; это означает, что спорить о поведении системы можно на функциональном уровне по отношению к спецификации, предотвращая слишком большую путаницу в вопросах реализации.
Продуманная разработка, определяемая спецификацией, допускает небольшую дискуссию об ошибках в сравнении с функциями; система, которая некорректно реализует спецификацию, неустойчива и должна быть исправлена.
Полагаю, эта идея настолько проникла в большинство из нас, что мы забываем о ее силе. Мой друг, работавший для небольшой программной фирмы восточнее Белвю, удивлялся, как разработчики Linux-приложений могут получать изменения операционной системы, синхронизированные с версиями приложений. В его компании главные системные API-интерфейсы часто изменялись, для того чтобы приспособиться к капризам приложений, и поэтому важнейшая функциональность системы часто должна была обновляться наряду с каждым приложением.
Я описал силу подчинения спецификациям и то, как от них зависит реализация, а затем перешел к утверждению, что приложение, которое получает неожиданный результат от документированного интерфейса, либо неверно спроектировано, либо содержит ошибку. Он нашел эту идею удивительной.
Распознавание таких ошибок является просто вопросом проверки реализации интерфейса относительно спецификации. Естественно, наличие исходного кода для данной реализации несколько упрощает это.
Кит Паккард.Позиция предшествующих стандартов имеет свои преимущества также и для конечных пользователей. Тогда как уже не маленькая компания восточнее Белвю имеет проблемы, сохраняя совместимость офисного набора с его предыдущими версиями, GUI-приложения, написанные в 1988 году, до сих пор работают без изменений на нынешних реализациях системы X. В мире Unix подобное долголетие является нормой, а причиной этого является позиция "стандарт как ДНК".
Таким образом, опыт показывает, что культура Unix, культивирующая уважение к стандартам, а также отбрасывание и переделку ошибочного кода, часто приводит к большей возможности взаимодействия в течение более продолжительного периода времени, чем постоянное исправление базы кода без стандарта, который обеспечивает управление и непрерывность. Это, несомненно, может быть одним из наиболее важных уроков Unix.
Последнее замечание Кита непосредственно приводит к вопросу, который выдвигается на передний план благодаря успеху Unix-систем с открытым исходным кодом — связь между открытыми стандартами и открытым исходным кодом. Данная проблема рассматривается в конце главы, но перед этим необходимо изучить практический вопрос: каким образом Unix-программисты могут действительно использовать огромную массу накопленных стандартов и как овладеть практическими знаниями для достижения переносимости программного обеспечения?
17.5. Программирование, обеспечивающее переносимость
Переносимость программ обычно рассматривается в квази-пространственных понятиях: возможно ли перенести данный код на существующее аппаратно-программное обеспечение, отличное от того, для которого код создавался? Однако десятки лет опыта Unix подсказывают, что долговечность во времени важна в той же степени, если не в большей. Если бы можно было подробно предсказать будущее программного обеспечения, то оно, вероятно, было бы настоящим. Тем не менее, в программировании, обеспечивающем переносимость, следует пытаться обдумывать варианты построения программ на основе тех функций окружающей системы, которые, вероятнее всего, сохранятся, и избегать технологий, которые, скорее всего, в обозримом будущем прекратят свое существование.
Что касается Unix, два десятка лет изучения вопросов определения переносимых API-интерфейсов позволили полностью решить данную проблему. Средства, описанные в Единой спецификации Unix, вероятно, будут присутствовать во всех современных Unix-платформах и вряд ли не будут поддерживаться в будущем.