Программирование на уровне компонентов
Наличие большого набора простых слов делает простым использование техники, которую мы назовем "программирование на уровне компонентов". Для пояснения давайте вначале прoсмотрим те объединения, которые мы неопределенно описали как "части, которые могут быть изменены". В типовой системе почти все может быть подвержено изменениям: устройства ввода/вывода, такие, как терминалы и принтеры, интерфейсы типа микросхем ПЛМ, операционные системы, любые структуры данных или их представление, любые алгоритмы и т.д.
Вопрос: "Как можно минимизировать вклад каждого из подобных изменений ? Как определить наименьший набор изменяемых вещей для обеспечения требуемых перемен ?"
Ответом является: "наименьший набор взаимовлияющих структур данных и алгоритмов, которые разделяют знание о том, как они в совокупности работают." Мы будем называть такое объединение "компонентом".
Компонент является ресурсом. Он может быть частью аппаратуры, например, ПЛМ или аппаратным стеком. Или компонент может быть программным ресурсом, таким, как очередь, словарь или программный стек.
Все компоненты включают в себя объекты данных и алгоритмы. Не имеет значения, физический ли это объект данных (такой, как аппаратный регистр) или абстрактный (как вершина стека или поле в базе данных). Безразлично, описан ли алгоритм в машинном коде или проблемно-ориентированными словами типа ОВСЯНКА или ЯЙЦА.
Рисунок 1-7 сопоставляет результаты структурированной разработки с результатами разработки на уровне компонентов. Вместо `модулей` под названиями ЧИТАТЬ-ЗАПИСЬ, РЕДАКТИРОВАТЬ-ЗАПИСЬ и ПИСАТЬ-ЗАПИСЬ мы сосредоточены на `компонентах`, описывающих структуру записей, реализующих систему команд редактора и обеспечивающих процедуры чтения/записи.
Что мы сделали ? Мы ввели новый этап в процесс разработки: разбили на компоненты во время `проектирования`, затем описали последовательность, иерархию и линию вход-обработка-выход при `реализации`. Да, это еще один шаг, однако мы получили дополнительное измерение для проведения разреза -- не только по слоям, но и `в клеточку`.
Рис.1-7. Структурированная разработка против разработки на уровне компонентов.
Последовательное/иерархическое проектирование:
+-----------------+ | обновить-запись | +-----------------+ | +---------------+--------------------+ | | | +-------|--------+ +----|-----------------+ +|--------------+ | СЧИТАТЬ-ЗАПИСЬ | | РЕДАКТИРОВАТЬ-ЗАПИСЬ | | ПИСАТЬ-ЗАПИСЬ | +----------------+ +----------------------+ +---------------+
Разработка по компонентам:
: ОБНОВИТЬ-ЗАПИСЬ ЗАПИСЬ ЧИТАТЬ РЕДАКТИРОВАТЬ ЗАПИСЬ ПИСАТЬ ; | \ | / | | \_______|___________/__ | | _______________|__________/ \ | | / | \ | +------|-/--+ +-----|----+ +----\----|-----+ | структура | | редактор | | программы | | записей | | | | записи/чтения | +-----------+ +----------+ +---------------+
Представим себе, что после того, как программа была написана, нам потребовалось изменить структуру записи. При последовательном, иерархическом проектировании это затронет все три модуля. При проектировании на уровне компонентов изменение коснется лишь компонента, описывающего структуру записи. Ничто другое, использующее этот компонент, не должно знать о перемене.
В дополнение к перечисленному преимущество такой схемы состоит в том, что программисты в группе могут получить в разработку индивидуальные компоненты с меньшей взаимозависимостью. Принцип программирования компонентов применим к руководству группой так же, как и к разработке программ.
Мы будем называть набор слов для описания компонента "лексиконом". (Одно из значений слова "лексикон" -- "набор слов, относящийся к определенному кругу интересов".) Лексикон -- это Ваш наружный интерфейс с компонентами (рис. 1-8).
Рис.1-8. Kомпонент описывается лексиконом.
ВЕЩЬ ДУХАЙКИ ВЕРТЕТЬ РАЗДВИГАТЬ ДЕЛО ТЕМА ПИХАТЬ ЦЕПЛЯТЬ ТОВАР ЧТОЭТО | КРУТИТЬ / | | \ / / | | \ / | +-|--\--------/----/--|-----------|--\---------/-----|------+ | |Объекты данных | | Алгоритмы (действия) | | | (вещи) / | ... \ | | | | \ * ------ ---> /| | | | /\ +---+ / \ |----| |
В данной книге слово "лексикон" относится только к тем словам компонента, которые используются по имени вне этого компонента. Компонент может содержать также определения, написанные исключительно для поддержки видимого снаружи лексикона. Мы будет называть вспомогательные определения "внутренними" словами.
Лексикон дает логические эквиваленты объектам данных и алгоритмам в форме имен. Лексикон вуалирует структуры данных и алгоритмы компонентов -- "как оно работает". Он представляет миру только "концептуальную модель" компонента, описанную простыми словами -- "что оно делает".
Эти слова затем становятся языком для описания структур данных и алгоритмов компонентов, написанных на более высоком уровне. "Что" для одного компонента становится "как" для высших компонентов.
Написанная на Форте задача состоит только из компонентов. Рисунок 1-9 показывает, как может быть разбита робототехническая задача.
Можно даже сказать, что лексикон -- это специализированный компилятор, написанный специально для поддержки кода высокоуровневой программы наиболее эффективным и надежным способом.
Между прочим, сам по себе Форт не поддерживает компоненты. Ему это не нужно. Компоненты -- это продукты разбиения программы ее проектировщиком. (В то же время Форт имеет "блоки" -- небольшие порции массовой памяти для хранения исходных текстов. Компонент обычно может быть написан в пределах одного или двух экранов Форта.)
Рис.1-9. Полная программа состоит из компонентов.
+--------------+ | Сварить кофе | +-/---------\--+ / \ / \ Лексикон Лексикон процессов перемещений робота робота / \ Лексикон Лексикон переключателей считывания / показаний Лексикон датчиков шагового / двигателя / \ / Корневой язык (Форт) \ / +---\------------/---+ | Реальный компьютер | +--------------------+
Важно понять, что лексикон может использоваться любым или всеми компонентами высших уровней. Ни один нормальный компонент `не` прячет свои компоненты поддержки, как это часто случается при послойном подходе к разработке.
Вместо этого каждый лексикон волен использовать все команды, определенные до него. Команда для движения робота опирается на корневой язык, со всеми его переменными, константами, операторами работы со стеком, математикой и др. так же сильно, как и на любой другой компонент.
Важным результатом такого подхода является то, что полная задача использует единый синтаксис, который легко выучить и соблюдать. Именно поэтому я использую слово "лексикон", а не "язык". У языков уникальные синтаксисы.
Доступность команд также значительно облегчает процесс тестирования и отладки. Интерактивность Форта позволяет программисту набирать и тестировать примитивные команды типа
ПРАВЫЙ ПЛЕЧО 20 ПОВЕРНУТЬ
"снаружи" так же просто, как и более мощные типа
ЛЕВЫЙ КОФЕЙНИК
В то же время программист может (при желании) намеренно запретить доступ конечного пользователя к любым командам, включая сам Форт, после того, как программа закончена.
Новая Форт-методология проясняется. Программирование на Форте состоит в расширении корневого языка в сторону приложения, определении новых команд, которые прямо описывают проблему.
Языки программирования, созданные специально для опеределенных применений, таких как робототехника, производственный контроль, статистика и т.д., известны как "проблемно-ориентированные". Форт -- это программные средства для `создания` проблемно-ориентированных языков. (Последняя фраза -- быть может, самое краткое из возможных описаний Форта.)
На самом деле Вам не стоит писать каких-либо серьезных задач на Форте; как язык, он просто недостаточно мощен. Вам `следует` писать на Форте свои собственные языки (лексиконы) для моделирования Вашего понимания проблемы, на которых Вы можете элегантно описать ее решение.