Предметно-ориентированные языки программирования
Мартин Фаулер
В этой книге известный эксперт в области программного обеспечения Мартин Фаулер предоставляет информацию, которая поможет вам определиться, следует ли использовать предметно-ориентированные языки для решения стоящих перед вами задач. Если применение предметно-ориентированных языков окажется оправданным, то вам пригодится вторая часть книги, в которой подробно, на конкретных примерах, описаны технологии, применяемые при создании таких языков.
Методы, описанные в данной книге, могут использоваться в большинстве современных объектно-ориентированных языков программирования. В основном примеры в книге написаны на Java и C#, но в некоторых из них использован Ruby. Все главы по возможности организованы в виде самодостаточных частей, а большинство справочных разделов - в знакомом читателю формате описания шаблонов программирования.
При правильном выборе и применении предметно-ориентированные языки могут существенно упростить сложный код, обеспечить эффективное общение с пользователями, повысить производительность и устранить узкие места разработки. В этой книге известный эксперт в области программного обеспечения Мартин Фаулер предоставляет информацию, которая поможет вам определиться, следует ли использовать предметно-ориентированные языки для решения стоящих перед вами задач. Если применение предметно-ориентированных языков окажется оправданным, то вам пригодится вторая часть книги, в которой подробно, на конкретных примерах, описаны технологии, применяемые при создании таких языков.
Издательство: Вильямс, 2011 г.
ISBN 978-5-8459-1738-6, 978-0-321-71294-3
Количество страниц: 576.
Содержание книги «Предметно-ориентированные языки программирования»:
- 17 Предисловие
- 24 Благодарности
- 27 Часть I. Описание
- 29 Глава 1. Вводный пример
- 29 1.1. Готическая безопасность
- 30 1.1.1. Контроллер мисс Грант
- 31 1.2. Модель конечного автомата
- 34 1.3. Программирование контроллера мисс Грант
- 41 1.4. Языки и семантическая модель
- 43 1.5. Использование генерации кода
- 46 1.6. Использование языковых инструментальных средств
- 48 1.7. Визуализация
- 29 1.1. Готическая безопасность
- 49 Глава 2. Использование предметно-ориентированных языков
- 49 2.1. Определение предметно-ориентированных языков
- 51 2.1.1. Границы DSL
- 53 2.1.2. Фрагментарные и автономные DSL
- 54 2.2. Зачем используется DSL
- 54 2.2.1. Повышение производительности разработки
- 55 2.2.2. Общение с экспертами в предметной области
- 56 2.2.3. Изменения в контексте выполнения
- 57 2.2.4. Альтернативные вычислительные модели
- 57 2.3. Проблемы с DSL
- 58 2.3.1. Языковая какофония
- 58 2.3.2. Стоимость построения
- 59 2.3.3. Язык гетто
- 59 2.3.4. Ограниченная абстракция
- 60 2.4. Более широкая обработка языка
- 60 2.5. Жизненный цикл DSL
- 62 2.6. Что такое хороший дизайн DSL
- 49 2.1. Определение предметно-ориентированных языков
- 63 Глава 3. Реализация предметно-ориентированных языков
- 63 3.1. Архитектура обработки DSL
- 67 3.2. Работа синтаксического анализатора
- 68 3.3. Грамматики, синтаксис и семантики
- 69 3.4. Анализ данных
- 72 3.5. Макросы
- 72 3.6. Тестирование DSL
- 73 3.6.1. Тестирование семантической модели
- 76 3.6.2. Тестирование синтаксического анализатора
- 80 3.6.3. Тестирование сценариев
- 80 3.7. Обработка ошибок
- 82 3.8. Миграция DSL
- 85 Глава 4. Реализация внутреннего DSL
- 85 4.1. Свободные API и API командных запросов
- 88 4.2. Необходимость в слое синтаксического анализа
- 89 4.3. Использование функций
- 93 4.4. Коллекции литералов
- 95 4.5. Использование грамматик для выбора внутренних элементов
- 96 4.6. Замыкания
- 98 4.7. Работа с синтаксическим деревом
- 100 4.8. Аннотации
- 101 4.9. Расширение литералов
- 101 4.10. Снижение синтаксического шума
- 102 4.11. Динамический отклик
- 103 4.12. Проверка типов
- 105 Глава 5. Реализация внешнего DSL
- 105 5.1. Стратегия синтаксического анализа
- 108 5.2. Стратегия получения вывода
- 110 5.3. Концепции синтаксического анализа
- 110 5.3.1. Лексический анализ
- 111 5.3.2. Грамматики и языки
- 112 5.3.3. Регулярные, контекстно-свободные и контекстно-зависимые грамматики
- 114 5.3.4. Нисходящий и восходящий синтаксический анализ
- 115 5.4. Смешивание с другим языком
- 117 5.5. XML DSL
- 119 Глава 6. Выбор между внутренними и внешними DSL
- 119 6.1. Обучение
- 120 6.2. Стоимость построения
- 121 6.3. Осведомленность программистов
- 121 6.4. Общение с экспертами предметной области
- 121 6.5. Смешивание в базовом языке
- 122 6.6. Границы строгой выразительности
- 123 6.7. Настройка времени выполнения
- 123 6.8. Скатывание в обобщенность
- 124 6.9. Соединение DSL
- 124 6.10. Подведение итогов
- 127 Глава 7. Альтернативные вычислительные модели
- 130 7.1. Несколько альтернативных моделей
- 130 7.1.1. Таблицы решений
- 130 7.1.2. Система правил вывода
- 132 7.1.3. Конечный автомат
- 132 7.1.4. Сеть зависимостей
- 133 7.1.5. Выбор модели
- 130 7.1. Несколько альтернативных моделей
- 135 Глава 8. Генерация кода
- 136 8.1. Выбор объекта генерации
- 138 8.2. Как генерировать код
- 139 8.3. Смешивание сгенерированного и рукописного кодов
- 140 8.4. Генерация удобочитаемого кода
- 141 8.5. Предварительный анализ генерации кода
- 141 8.6. Источники дополнительной информации
- 143 Глава 9. Языковые инструментальные средства
- 143 9.1. Элементы языковых инструментальных средств
- 144 9.2. Языки определения схем и метамодели
- 149 9.3. Редактирование исходного текста и проекционное редактирование
- 151 9.3.1. Множественные представления
- 151 9.4. Иллюстративное программирование
- 153 9.5. Тур по инструментам
- 154 9.6. Языковые инструментальные средства и CASE-инструменты
- 155 9.7. Следует ли использовать языковые инструментальные средства
- 157 Часть II. Общие вопросы
- 159 Глава 10. Зоопарк DSL
- 159 10.1. Graphviz
- 160 10.2. JMock
- 162 10.3. CSS
- 163 10.4. Hibernate Query Language (HQL )
- 164 10.5. XAML
- 166 10.6. FIT
- 167 10.7. Make и другие
- 171 Глава 11. Семантическая модель
- 171 11.1. Как это работает
- 173 11.2. Когда это использовать
- 174 11.3. Вводный пример (Java )
- 177 Глава 12. Таблица символов
- 177 12.1. Как это работает
- 179 12.1.1. Статически типизированные символы
- 180 12.2. Когда это использовать
- 180 12.3. Дополнительная литература
- 180 12.4. Сеть зависимостей во внешнем DSL (Java и ANTLR )
- 182 12.5. Использование символьных ключей во внутреннем DSL (Ruby )
- 183 12.6. Использование перечислений для статически типизированных символов (Java )
- 177 12.1. Как это работает
- 187 Глава 13. Переменная контекста
- 187 13.1. Как это работает
- 188 13.2. Когда это использовать
- 188 13.3. Чтение INI-файла (C#)
- 191 Глава 14. Построитель конструкции
- 191 14.1. Как это работает
- 192 14.2. Когда это использовать
- 192 14.3. Построение простых полетных данных (C#)
- 195 Глава 15. Макрос
- 195 15.1. Как это работает
- 196 15.1.1. Текстовые макросы
- 199 15.1.2. Синтаксические макросы
- 202 15.2. Когда это использовать
- 195 15.1. Как это работает
- 205 Глава 16. Уведомление
- 205 16.1. Как это работает
- 206 16.2. Когда это использовать
- 206 16.3. Очень простое уведомление (C#)
- 207 16.4. Уведомление анализа (Java )
- 211 Часть III. Вопросы создания внешних DSL
- 213 Глава 17. Трансляция, управляемая разделителями
- 213 17.1. Как это работает
- 216 17.2. Когда это использовать
- 216 17.3. Карты постоянных клиентов (C#)
- 217 17.3.1. Семантическая модель
- 219 17.3.2. Синтаксический анализатор
- 221 17.4. Синтаксический анализ неавтономных инструкций контроллера мисс Грант (Java )
- 229 Глава 18. Синтаксически управляемая трансляция
- 230 18.1. Как это работает
- 231 18.1.1. Лексический анализатор
- 233 18.1.2. Синтаксический анализатор
- 235 18.1.3. Генерация вывода
- 236 18.1.4. Семантические предикаты
- 236 18.2. Когда это использовать
- 236 18.3. Дополнительная литература
- 230 18.1. Как это работает
- 237 Глава 19. Форма Бэкуса–Наура
- 237 19.1. Как это работает
- 239 19.1.1. Символы множественности (операторы Клини)
- 240 19.1.2. Другие полезные операторы
- 240 19.1.3. Грамматики, разбирающие выражения
- 241 19.1.4. Преобразование РБНФ в БНФ
- 243 19.1.5. Действия
- 245 19.2. Когда это использовать
- 237 19.1. Как это работает
- 247 Глава 20. Лексический анализатор на основе таблицы регулярных выражений
- 248 20.1. Как это работает
- 249 20.2. Когда это использовать
- 249 20.3. Лексический анализатор контроллера мисс Грант (Java)
- 253 Глава 21. Синтаксический анализатор на основе рекурсивного спуска
- 254 21.1. Как это работает
- 257 21.2. Когда это использовать
- 257 21.3. Дополнительная литература
- 257 21.4. Рекурсивный спуск и контроллер мисс Грант (Java )
- 263 Глава 22. Комбинатор синтаксических анализаторов
- 264 22.1. Как это работает
- 267 22.1.1. Выполнение действий
- 268 22.1.2. Функциональный стиль комбинаторов
- 268 22.2. Когда это использовать
- 269 22.3. Комбинаторы синтаксических анализаторов и контроллер мисс Грант (Java )
- 264 22.1. Как это работает
- 277 Глава 23. Генератор синтаксических анализаторов
- 277 23.1. Как это работает
- 278 23.1.1. Встроенные действия
- 280 23.2. Когда это использовать
- 280 23.3. Hello World (Java и ANTLR )
- 281 23.3.1. Написание базовой грамматики
- 282 23.3.2. Построение синтаксического анализатора
- 284 23.3.3. Добавление кода действий в грамматику
- 286 23.3.4. Применение шаблона Generation Gap
- 277 23.1. Как это работает
- 289 Глава 24. Построение дерева
- 289 24.1. Как это работает
- 291 24.2. Когда это использовать
- 292 24.3. Использование синтаксиса построения дерева ANTLR (Java и ANTLR )
- 293 24.3.1. Токенизация
- 294 24.3.2. Синтаксический анализ
- 296 24.3.3. Наполнение семантической модели
- 299 24.4. Построение дерева с использованием кода действий (Java и ANTLR )
- 305 Глава 25. Встроенная трансляция
- 305 25.1. Как это работает
- 306 25.2. Когда это использовать
- 306 25.3. Контроллер мисс Грант (Java и ANTLR)
- 311 Глава 26. Встроенная интерпретация
- 311 26.1. Как это работает
- 311 26.2. Когда это использовать
- 312 26.3. Калькулятор (ANTLR и Java )
- 315 Глава 27. Внешний код
- 315 27.1. Как это работает
- 317 27.2. Когда это использовать
- 317 27.3. Встраивание динамического кода (ANTLR, Java и Javascript)
- 318 27.3.1. Семантическая модель
- 320 27.3.2. Синтаксический анализатор
- 325 Глава 28. Альтернативная токенизация
- 325 28.1. Как это работает
- 326 28.1.1. Кавычки
- 328 28.1.2. Лексическое состояние
- 330 28.1.3. Изменение типа токена
- 331 28.1.4. Игнорирование типов токенов
- 332 28.2. Когда это использовать
- 325 28.1. Как это работает
- 333 Глава 29. Вложенные операторные выражения
- 333 29.1. Как это работает
- 334 29.1.1. Применение восходящих синтаксических анализаторов
- 335 29.1.2. Нисходящие синтаксические анализаторы
- 337 29.2. Когда это использовать
- 333 29.1. Как это работает
- 339 Глава 30. Символ новой строки в качестве разделителя
- 339 30.1. Как это работает
- 341 30.2. Когда это использовать
- 343 Глава 31. Прочие вопросы
- 343 31.1. Синтаксические отступы
- 345 31.2. Модулярная грамматика
- 347 Часть IV. Вопросы создания внутренних DSL
- 349 Глава 32. Построитель выражений
- 350 32.1. Как это работает
- 350 32.2. Когда это использовать
- 351 32.3. Свободный календарь с построителем и без него (Java)
- 353 32.4. Использование для календаря нескольких построителей (Java)
- 357 Глава 33. Последовательность функций
- 357 33.1. Как это работает
- 358 33.2. Когда это использовать
- 358 33.3. Простая конфигурация компьютера (Java)
- 361 Глава 34. Вложенные функции
- 361 34.1. Как это работает
- 363 34.2. Когда это использовать
- 363 34.3. Простой пример конфигурации компьютера (Java)
- 365 34.4. Обработка различных аргументов с помощью токенов (C#)
- 366 34.5. Использование токенов подтипов для поддержки интегрированной среды разработки (Java)
- 368 34.6. Использование инициализаторов объектов (C#)
- 369 34.7. Повторяющиеся события (C#)
- 369 34.7.1. Семантическая модель
- 372 34.7.2. DSL
- 375 Глава 35. Соединение методов в цепочки
- 375 35.1. Как это работает
- 377 35.1.1. Построители или значения
- 377 35.1.2. Проблема окончания
- 378 35.1.3. Иерархическая структура
- 378 35.1.4. Последовательные интерфейсы
- 379 35.2. Когда это использовать
- 379 35.3. Простой пример конфигурации компьютера (Java )
- 383 35.4. Соединение методов в цепочки со свойствами (C#)
- 383 35.5. Последовательные интерфейсы (C#)
- 375 35.1. Как это работает
- 387 Глава 36. Перенос области видимости в объект
- 388 36.1. Как это работает
- 388 36.2. Когда это использовать
- 389 36.3. Коды безопасности (C#)
- 389 36.3.1. Семантическая модель
- 391 36.3.2. DSL
- 393 36.4. Использование вычисления экземпляра (Ruby )
- 395 36.5. Использование инициализатора экземпляра (Java )
- 397 Глава 37. Замыкание
- 397 37.1. Как это работает
- 401 37.2. Когда это использовать
- 403 Глава 38. Вложенные замыкания
- 403 38.1. Как это работает
- 405 38.2. Когда это использовать
- 405 38.3. Заворачивание последовательности функций во вложенное замыкание (Ruby)
- 407 38.4. Простой пример (C#)
- 408 38.5. Применение соединения методов в цепочки (Ruby )
- 410 38.6. Последовательность функций с явными аргументами замыканий (Ruby )
- 411 38.7. Применение вычисления экземпляра (Ruby )
- 415 Глава 39. Список литералов
- 415 39.1. Как это работает
- 415 39.2. Когда это использовать
- 417 Глава 40. Ассоциативные массивы литералов
- 417 40.1. Как это работает
- 418 40.2. Когда это использовать
- 418 40.3. Настройка конфигурации компьютера с помощью списков и отображений (Ruby )
- 419 40.4. Имитация Lisp (Ruby )
- 423 Глава 41. Динамический отклик
- 424 41.1. Как это работает
- 424 41.2. Когда это использовать
- 426 41.3. Расчет бонусов с помощью анализа имен методов (Ruby )
- 426 41.3.1. Модель
- 428 41.3.2. Построитель
- 429 41.4. Расчет бонусов с помощью цепочек вызовов (Ruby )
- 430 41.4.1. Модель
- 430 41.4.2. Построитель
- 433 41.5. Уменьшение шума в коде контроллера тайника (JRuby )
- 439 Глава 42. Аннотации
- 440 42.1. Как это работает
- 440 42.1.1. Определение аннотации
- 441 42.1.2. Обработка аннотаций
- 442 42.2. Когда это использовать
- 443 42.3. Пользовательский синтаксис с обработкой времени выполнения (Java )
- 445 42.4. Использование метода класса (Ruby )
- 446 42.5. Динамическая генерация кода (Ruby )
- 440 42.1. Как это работает
- 449 Глава 43. Работа с синтаксическим деревом
- 449 43.1. Как это работает
- 450 43.2. Когда это использовать
- 451 43.3. Генерация запросов IMAP из условий C# (C#)
- 452 43.3.1. Семантическая модель
- 454 43.3.2. Построение из исходного текста C#
- 458 43.3.3. Отступление
- 461 Глава 44. Класс таблицы символов
- 462 44.1. Как это работает
- 462 44.2. Когда это использовать
- 463 44.3. Статически типизированный класс таблицы символов (Java )
- 469 Глава 45. Шлифовка текста
- 469 45.1. Как это работает
- 470 45.2. Когда это использовать
- 470 45.3. Шлифовка правил дисконта (Ruby )
- 473 Глава 46. Расширение литералов
- 473 46.1. Как это работает
- 474 46.2. Когда это использовать
- 474 46.3. Ингредиенты рецепта (C#)
- 477 Часть V. Альтернативные вычислительные модели
- 479 Глава 47. Адаптивная модель
- 480 47.1. Как это работает
- 481 47.1.1. Внедрение императивного кода в адаптивную модель
- 483 47.1.2. Инструментарий
- 483 47.2. Когда это использовать
- 480 47.1. Как это работает
- 485 Глава 48. Таблицы принятия решений
- 485 48.1. Как это работает
- 487 48.2. Когда это использовать
- 487 48.3. Вычисление оплаты заказа (C#)
- 487 48.3.1. Модель
- 491 48.3.2. Синтаксический анализатор
- 495 Глава 49. Сеть зависимостей
- 496 49.1. Как это работает
- 498 49.2. Когда это использовать
- 498 49.3. Анализ зелий (C#)
- 499 49.3.1. Семантическая модель
- 500 49.3.2. Синтаксический анализатор
- 503 Глава 50. Система правил вывода
- 504 50.1. Как это работает
- 505 50.1.1. Цепочки выводов
- 505 50.1.2. Противоречивые выводы
- 506 50.1.3. Шаблоны в структуре правила
- 507 50.2. Когда это использовать
- 507 50.3. Проверка для членства в клубе (C#)
- 507 50.3.1. Модель
- 508 50.3.2. Синтаксический анализатор
- 509 50.3.3. Развитие DSL
- 511 50.4. Правила избрания: расширение членства в клубе (C#)
- 512 50.4.1. Модель
- 514 50.4.2. Синтаксический анализатор
- 504 50.1. Как это работает
- 517 Глава 51. Конечный автомат
- 517 51.1. Как это работает
- 519 51.2. Когда это использовать
- 519 51.3. Контроллер тайника (Java)
- 521 Часть VI. Генерация кода
- 523 Глава 52. Генерация с помощью преобразователя
- 523 52.1. Как это работает
- 524 52.2. Когда это использовать
- 525 52.3. Контроллер тайника (Java генерирует C)
- 529 Глава 53. Шаблонная генерация
- 529 53.1. Как это работает
- 531 53.2. Когда это использовать
- 531 53.3. Генерация конечного автомата тайника с помощью вложенных условных конструкций (Velocity и Java, генерирующие C)
- 537 Глава 54. Встроенный помощник
- 538 54.1. Как это работает
- 538 54.2. Когда это использовать
- 539 54.3. Состояния тайника (Java и ANTLR)
- 541 54.4. Должен ли помощник генерировать HTML (Java и Velocity)
- 545 Глава 55. Генерация, осведомленная о модели
- 546 55.1. Как это работает
- 546 55.2. Когда это использовать
- 546 55.3. Конечный автомат тайника (C)
- 553 55.4. Динамическая загрузка конечного автомата (C)
- 557 Глава 56. Генерация, игнорирующая модель
- 557 56.1. Как это работает
- 558 56.2. Когда это использовать
- 558 56.3. Конечный автомат тайника как вложенные условные конструкции (C)
- 561 Глава 57. Отделение генерируемого кода с помощью наследования
- 562 57.1. Как это работает
- 563 57.2. Когда это использовать
- 563 57.3. Генерация классов из схемы данных (Java и немного Ruby)
- 569 Список литературы
- 570 Предметный указатель
Инструкция как скачать книгу Мартин Фаулер: Предметно-ориентированные языки программирования в форматах DjVu, PDF, DOC или fb2 совершенно бесплатно.