Искусство программирования для Unix
Шрифт:
Другими более очевидными кандидатами для такого разграничения были бы фильтры. Однако фильтры в не-Unix-средах встречаются чаще, чем пары ядро/интерфейс с двунаправленной передачей данных между ними. Имитировать конвейеры просто. Сложно реализовать более развитые IPC-механизмы, необходимые для пар ядро/интерфейс.
Оуэн Тейлор (Owen Taylor), куратор библиотеки GTK+, широко используемой для создания пользовательских интерфейсов в системе X, превосходно показал технические преимущества данного вида разделения в конце своей заметки "Why GTK_MODULES is not a security hole" <http://www.gtk.org/setuid.html>. Он заканчивает статью так: "Безопасной setuid-программой
Эта идея не нова. Ранние исследования сотрудников центра Xerox PARC в области графических пользовательских интерфейсов привели их к созданию схемы "модель-отображение-контроллер" (model-view-controller) как прототипа для GUI-интерфейсов.
• "Модель" в данном случае — то, что в мире Unix обычно называется "ядром" (engine). Модель содержит структуры данных, зависящие от предметной области, и логику приложения. Серверы баз данных являются основными примерами моделей.
• В часть "отображение" входит то, что приводит объекты предметной области в визуальную форму. В приложении с действительно четко разделенными "моделью/отображением/контроллером" компонент отображения извещается об обновлениях модели и отвечает скорее самостоятельно, а не под синхронным управлением контроллера или явных запросов на обновление.
• Компонент "контроллер" обрабатывает пользовательские запросы и передает их модели в виде команд.
На практике части "отображение" и "контроллер" часто сильнее связаны друг с другом, чем с моделью. Например, в большинстве GUI-интерфейсов комбинируется поведение частей "отображения" и "контроллера". Они разделяются только в тех случаях, когда приложение требует нескольких видов отображения модели.
Схема модель/отображение/контроллер в операционной системе Unix распространена гораздо шире, чем в других средах, именно потому, что существует прочная традиция "решать одну задачу хорошо", а IPC-методы являются одновременно простыми и гибкими.
Особенно мощная форма данной методики связывает интерфейс политики (часто GUI-интерфейс, комбинирующий функции отображения и контроллера) с ядром (моделью), который содержит интерпретатор для узкоспециального мини-языка. Данная модель проектирования рассматривалась в главе 8, где основное внимание было уделено конструкциям мини-языков. Здесь рассматриваются различные способы, с помощью которых такие ядра могут формировать компоненты более крупных систем кода.
Существует несколько основных вариантов данной модели проектирования.
11.6.8.1. Пара конфигуратор/актор
В данной паре интерфейсная часть управляет средой запуска фильтра или программы, подобной демону, которая затем выполняется, не требуя пользовательских команд.
Хорошим примером пары конфигуратор/актор являются программы fetchmail(1) и fetchmaileonf(1) (которые уже использовались как учебные примеры воспринимаемости и создания программ, управляемых данными, а также рассматриваются в главе 14 как учебные примеры использования языка Python). Утилита fetchmailconf представляет собой интерактивный конфигуратор файлов профилей, который поставляется с программой fetchmail. fetchmailconf также может служить в качестве GUI-упаковщика, который запускает fetchmail
Данная модель проектирования позволяет обеим программам, fetchmail и fetchmailconf, специализироваться в том, что они делают хорошо, и конечно, позволяет писать их на различных языках, которые целесообразно использовать в данных предметных областях. Программу fetchmail, которая обычно запускается в фоновом режиме как демон, не требуется объединять с GUI-кодом, и наоборот, fetchmailconf может специализироваться на сложном GUI-представлении, не требуя от fetchmail затрат размера и сложности. Наконец, ввиду того, что информационные каналы между ними являются узкими и четко определенными, остается возможность управлять программой fetchmail из командной строки, а также из сценариев, отличных от fetchmailconf.
Термин "конфигуратор/актор" придуман автором данной книги.
11.6.8.2. Пара спулер/демон
Облегченный вариант пары конфигуратор/актор может оказаться полезным в ситуациях, когда требуется сериализованный доступ к общему ресурсу в пакетном режиме, т.е. когда четко определенный поток заданий или последовательность запросов требует некоторого совместно используемого ресурса, но ни одна отдельная задача не требует взаимодействия с пользователем.
В данной модели спулер или клиентская часть просто помещает запросы на выполнение заданий и данные в спул-область. Запросы на выполнение заданий и данные — просто файлы, а спул-областью, как правило, является каталог. Расположение данного каталога и формат запросов согласовывается между спулером и демоном.
Демон постоянно работает в фоновом режиме, опрашивая спул-каталог в поисках задания. Когда он находит запрос на выполнение задания, то пытается обработать связанные с ним данные. Если обработка прошла успешно, то запрос и данные из спул-области удаляются.
Классическим примером данной модели является система спулера печати Unix, lpr(1)/lpd(1). Интерфейсной частью в данном случае является утилита lpr(1), просто помещающая предназначенные для печати файлы в спул-область, которая периодически сканируется демоном lpd. Задача данного демона — сериализация доступа к печатающим устройствам.
Другим классическим примером является пара at(1)/atd(1), обеспечивающая выполнение команд по расписанию. Третьим исторически важным примером, хотя и не распространенным в настоящее время, была программа UUCP (Unix-to-Unix Copy Program), широко применявшаяся в качестве почтового транспорта на коммутируемых линиях до того, как в начале 90-х годов прошлого века не начался взрывной рост Internet.
Модель спулер/демон и сейчас остается важной в программах транспортировки почты (которые по своей природе являются пакетными). Интерфейсные части почтовых транспортных программ, таких как sendmail(1) и qmail(1), обычно предпринимают одну попытку немедленной доставки почты через SMTP-сервер и внешнее Internet-соединение. Если попытка не удалась, то почта помещается в спул-область; демон-версия или режим почтового транспорта попытается доставить почту позднее.