Искусство программирования для Unix
Шрифт:
8.2.12 Учебный пример: JavaScript
JavaScript — язык с открытым исходным кодом, спроектированный для внедрения в С-программы. Несмотря на то, что он также встраивается в Web-серверы, первоначальным и наиболее известным его проявлением является клиентский JavaScript, который позволяет встраивать исполняемый код в Web-страницы, просматриваемые любым поддерживающим его браузером. Здесь рассматривается именно эта версия языка.
JavaScript — интерпретируемый язык, полностью попадающий под определения
Несмотря на все указанные особенности, клиентская версия JavaScript не является полностью универсальным языком. Его возможности жестко ограничены в целях предотвращения атак на браузеры через Web-страницы, содержащие JavaScript-код. Язык принимает входные данные от пользователя и генерирует или модифицирует Web-страницы, но непосредственно не может изменять содержимое дисковых файлов и открывать собственные сетевые соединения.
С течением времени данный язык стал более универсальным и менее связанным со своей клиентской средой. Это закономерное развитие любого удачного специализированного языка. Клиентский вариант JavaScript в настоящее время взаимодействует со своим окружением путем чтения и записи значений в один специальный объект, который называется документной объектной моделью браузера (Document Object Model, DOM). Данный язык до сих пор имеет некоторые устаревшие API-интерфейсы для связи с браузером, которые не работают через DOM, однако они нежелательны, отсутствуют в стандарте для JavaScript ЕСМА-262 и могут не поддерживаться в будущих версиях.
Стандартным справочником по JavaScript является книга "JavaScript: The Definitive Guide" [20]. Исходный код доступен в Web67. Язык JavaScript представляет собой интересный пример для изучения по двум причинам. Во-первых, он максимально близок к универсальному языку, фактически не являясь таковым. Во-вторых, связь между клиентским JavaScript и средой браузера через единственный DOM-объект хорошо спроектирована и может послужить моделью для других ситуаций встраивания.
8.3. Проектирование мини-языков
В каких ситуациях целесообразна разработка мини-языка? Выше отмечалось, что мини-языки предоставляют способ перемещения спецификаций проблем на более высокий уровень, а в нескольких учебных примерах это наблюдение подтверждалось фактами. Оборотная сторона данного явления — использование мини-языка, вероятно, будет хорошим подходом всякий раз, когда примитивы предметной области просты и стереотипны, а способы их вероятного применения пользователями изменчивы.
Некоторые родственные идеи можно найти в описании моделей проектирования "Alternate Hard And Soft Layers" <http://www.c2.com/cgi/wiki7Alternate-HardAndSoftLayers>
Интересное обозрение стилей и методик разработки с помощью мини-языков приведено в статье "Notable Design Patterns for Domain-Specific Languages" [77].
8.3.1. Определение соответствующего уровня сложности
Первым важным моментом, о котором необходимо помнить при разработке мини-языка, является, как обычно, сохранение по возможности простой конструкции. Диаграмма классификации, которая использовалась для организации учебных примеров, выражает иерархию сложности. Необходимо удерживать конструкцию как можно ближе к левой границе схемы. Если с проблемой можно справиться путем разработки структурированного файла данных вместо использования мини-языка, который стремится модифицировать внешние данные, в случае если он является интерпретируемым, то следует любыми средствами реализовать эту возможность.
Одной чрезвычайно прагматичной причиной, по которой следует продолжать усердно работать со структурированными данными, а не с мини-языком, является то, что в сетевом мире средства встроенного мини-языка являются предметом неправильного использования, которое может причинять беспокойство или даже быть опасным. JavaScript — главный экземпляр в категории "причиняющих беспокойство". Разработчики данного языка не предвидели того, что он будет использоваться для всплывающей рекламы настолько навязчиво, что создаст потребность в функциях браузера, подавляющих интерпретацию JavaScript.
Макровирусы Microsoft Word показывают, как мини-язык может стать действительно опасной брешью в безопасности системы, простои и потери производительности от которой ежегодно обходятся в миллиарды долларов. Полезно отметить, что несмотря на существование в мире как минимум 20 млн. пользователей68 Unix, в Unix-среде никогда не было вспышек макровирусов, характерных для Windows. Существует множество причин этому, включая принципиально лучшую с точки зрения безопасности конструкцию Unix; но по крайней мере одной причиной является тот факт, что почтовые агенты в Unix по умолчанию не обрабатывают исполняемое содержимое в документах, просматриваемых пользователем".
Если существует какая-либо возможность того, что пользователи приложения могут запускать программы из неблагонадежных источников, рискованные функции мини-языка приложения могут в конце концов привести к необходимости его подавления. Языки, подобные Java и JavaScript, явно изолируются в "песочнице", т.е. они имеют ограниченный доступ к своему окружению. Это сделано не только для того, чтобы упростить их конструкцию, но и для того, чтобы воспрепятствовать потенциально деструктивным операциям со стороны ошибочного или злонамеренного кода.