Назад Оглавление Вперед
На головную страницу М.М.Горбунов-Посадов
 
РАСШИРЯЕМЫЕ ПРОГРАММЫ
 

 Г л а в а  1
ОФОРМЛЕНИЕ ВАРИАНТА
 
1.8. Специализированные средства
 

 

1.8. Специализированные средства

      1.8.1. Недостатки доморощенных решений. В предшествующих разделах разбирались разнообразные решения задачи оформления варианта, основанные на использовании различных широко распространенных штатных средств программного обеспечения. Рассмотренный список решений далеко не полон, его можно было бы и продолжить. Тем не менее приведенных сведений достаточно, чтобы сделать некоторые выводы.
      Прежде всего отметим, что квалифицированный программист, работая в практически любой операционной среде, сумеет найти относительно приемлемое решение задачи оформления варианта. В то же время нерационально, по-видимому, многократно расходовать потенциал находчивости и изобретательности программиста для решения одной и той же достаточно часто встречающейся задачи. Но главная беда в другом: любое из таких доморощенных решений, опирающихся на возможности штатных средств, страдает рядом недостатков.
      Наиболее характерными из них являются возможность потери работоспособности отлаженной ранее версии (нарушение требования безболезненности изменений) и дублирование исходного текста программы. Кроме того, использование штатных средств, ориентированных на несколько иные задачи, запутывает последующий анализ программы, поскольку по внешнему виду формируемых таким образом конструкций бывает трудно определить, предназначаются ли они для оформления варианта или же для каких-либо других целей.

      1.8.2. Набор операций. Попытаемся представить себе, как можно было бы избавиться от перечисленных недостатков. Рассматривая доморощенные решения, мы всякий раз убеждались в том, что среди распространенных штатных системных средств не удается найти инструмента, удовлетворяющего нас в полной мере. Теперь мы изберем другой путь, а именно допустим, что при создании некоторой новой операционной среды в число наиболее приоритетных целей вошла и задача рациональной организации оформления варианта. Тогда в разрабатываемый проект будут, вероятно, включены системные средства, специально предназначенные для ее решения. Последовательность действий по оформлению варианта в созданной таким образом среде могла бы выглядеть так.
      Сначала в исходном тексте программы выделяется вариантный фрагмент. Сделать это можно, например, посредством указания начального и конечного символов, но лучше, если квантами выделения будут синтаксические единицы языка программирования. Тем самым формируется вариантное гнездо, т. е. указывается место в тексте, предназначенное для подстановки одного из имеющихся вариантных фрагментов.
      В момент формирования гнезда единственным претендентом на размещение в нем является только что выделенный вариантный фрагмент исходного текста. Однако теперь программист получает возможность образовать для вновь сформированного гнезда еще один вариантный фрагмент. Новый фрагмент можно объявить активным, т. е. включить в формируемую версию выполняемой программы, вытесняя из нее старый фрагмент. В то же время в программном фонде старый фрагмент сохраняется, там оба вариантных фрагмента сосуществуют на равных правах (рис. 1.5).


 
Рис. 1.5.  Оформление варианта специализированными средствами.
а — исходный текст,  б — текст с вариантным гнездом,
в, г — вариантные фрагменты

Затем, разумеется, можно снова сделать активным старый фрагмент, или же образовать в данном гнезде еще один вариантный фрагмент и сделать активным его и т. д.
      Любой из вариантных фрагментов можно уничтожить. Если у гнезда останется только один принадлежащий ему вариантный фрагмент, то можно ликвидировать и гнездо, т. е. сделать данный участок программы безвариантным. При ликвидации единственный принадлежащий гнезду вариантный фрагмент подставляется на место гнезда и полностью сливается с окружающим текстом программы.

      1.8.3. Безболезненность и другие полезные свойства. Как и следовало ожидать, усилия по созданию специализированных средств не пропали даром. Приведенная схема оформления варианта превосходит любое из разобранных ранее доморощенных решений, пытавшихся противостоять неприспособленности распространенных операционных сред.
      Действительно, в приведенном решении все изменения программы производятся безболезненно, не нарушая работоспособности отлаженных версий, поскольку ни на одной стадии процессов оформления и ликвидации варианта не требуется редактирование текста, существовавшего ранее. Исключается какое бы то ни было дублирование текстов программ. Наконец, вариант оформляется посредством специально предназначенных для этой цели конструкций, что позволяет легко распознать присутствие вариантности при последующем анализе программы.
      Обсуждая безболезненность приведенного решения, имеет смысл рассмотреть еще одну грань данной проблемы. Пусть программа, в которой вы намереваетесь оформить вариантный фрагмент, интенсивно используется вашими коллегами для проведения важных расчетов. Тогда, обеспечивая безболезненность оформления варианта, необходимо в первую очередь позаботиться о том, чтобы ваше экспериментирование не отразилось на работе соседей.
      Точнее говоря, хотелось бы, чтобы все то время, которое вы посвятите отладке нового варианта, ваши коллеги могли бы не подозревать об ожидающем их сюрпризе — появлении новой модификации алгоритма — и продолжать работать со старой версией программы. Для этого достаточно слегка видоизменить предложенную выше схему, а именно считать, что старый вариантный фрагмент подставляется во вновь образованное вариантное гнездо по умолчанию. Тогда вам придется явно указывать новый вариантный фрагмент в описании конфигурации своей экспериментальной версии программы. А ваши коллеги в это время будут как ни в чем не бывало использовать прежнее описание конфигурации, отражающее старую отлаженную версию.
      Отметим, что здесь понятие безболезненности затрагивает уже не только тексты программ, но и описание конфигурации. Такое обобщение следует признать совершенно естественным. Ведь для ваших коллег практически безразлично, редактирование какого текста (программы или описания конфигурации) приведет к потере работоспособности.

      1.8.4. Имена. Внешнее оформление приведенного решения может быть самым различным. Так, например, при просмотре текста программы вариантное гнездо может представляться либо специальной языковой конструкцией, либо подставленным на место гнезда (и выделенным цветом или яркостью) активным вариантным фрагментом. Ввод, просмотр и редактирование вариантных фрагментов могут вестись либо изолированно, либо в окружении примыкающего к гнезду текста программы. По-разному может быть решен и вопрос о статусе вариантных фрагментов в программном фонде. Эти фрагменты могут либо рассматриваться как подчиненные объекты по отношению к части программы, содержащей соответствующее вариантное гнездо, либо обрести большую самостоятельность и даже получить те же права, что и все остальные хранящиеся в программном фонде части программ.
      Прежде чем говорить о достоинствах того или иного статуса вариантных фрагментов, отметим, что в предшествующем изложении набора операций для оформления варианта не были разделены процессы формирования программной конфигурации и управления ею. На самом деле эти процессы происходят обычно в разное время и соседствуют с различными видами работ. Формирование конфигурации (формирование гнезда, образование и уничтожение вариантных фрагментов, ликвидация гнезда) примыкает к работам по развитию программного фонда, а управление конфигурацией (смена активного вариантного фрагмента) — к сборке и запуску выполняемой программы, заданию исходных данных и т. д.
      Смену активного вариантного фрагмента можно организовать по-разному. Если переключение с одного варианта на другой производится достаточно редко, то можно не присваивать имен ни гнезду, ни фрагментам. Программист указывает интересующее его гнездо непосредственно в тексте программы, вслед за чем ему предъявляются тексты всех принадлежащих этому гнезду вариантных фрагментов, среди которых он и выбирает активируемый. Но с ростом частоты переключений выполнение подобных манипуляций с исходными текстами в процессе подготовки расчета может оказаться обременительным.
      В этом случае более экономичное решение можно получить, присвоив вариантным фрагментам имена. Использование имен позволяет управлять конфигурацией выполняемой программы извне, не имея перед глазами соответствующего гнезда, а лишь указывая имя требуемого в формируемой программе фрагмента.
      У данного решения есть еще одно преимущество. Вариантные фрагменты, обретшие имена, становятся в известной мере полноценными элементами программного фонда, поскольку появляется возможность выполнять над ними те же операции (просмотр, редактирование, распечатка, поиск и др.), что и над любыми другими автономными частями программы. Разумеется, самостоятельность такого фрагмента все же несколько ограничена: где-то в недрах программного фонда должна храниться информация о его происхождении, т. е. о подчинении конкретному вариантному гнезду. Поэтому, например, при уничтожении участка текста, содержащего гнездо, по-видимому, автоматически должны исчезнуть и все привязанные к этому гнезду вариантные фрагменты.
      Именование фрагментов имеет, однако, и теневую сторону. Если вариантных фрагментов много, то могут возникнуть трудности с подбором для них имен, уникальных в рамках всего программного фонда. Выйти из положения можно, разрешив именовать не только фрагменты, но и гнездо. Тогда уникальность имени потребуется лишь для гнезда, а относящиеся к гнезду вариантные фрагменты получат в программном фонде составные имена

имя_гнезда . имя_вариантного_фрагмента

(Здесь и далее наклонным шрифтом рубленой гарнитуры выделены нетерминальные символы.)
      Конкретную конфигурацию программы теперь можно будет задавать посредством назначений вида

имя_гнезда < имя_вариантного_фрагмента

При разумном подборе мнемоничных имен такие конструкции оказываются довольно наглядными. Так, если требуется конкретная конфигурация, использующая метод Эйлера и хешированную таблицу (см. примеры в разд. 1.1, 1.4), то для задания ее следует написать

МЕТОД<– ЭЙЛЕР
ДОСТУП<– ХЕШИРОВАНИЕ

где МЕТОД и ДОСТУП — имена вариантных гнезд, отвечающих, соответственно, за метод расчета и организацию таблицы, а ЭЙЛЕР и ХЕШИРОВАНИЕ — имена фрагментов, реализующих требуемые варианты.
      Наличие у гнезда имени позволяет не обращаться к месту расположения гнезда в программе при заведении нового вариантного фрагмента, при просмотре существующих вариантных фрагментов и т. д. Во всех подобных случаях теперь достаточно указать имя гнезда. Вместе с тем возможность непосредственного перехода к текстам соответствующих вариантных фрагментов из места расположения гнезда также должна быть сохранена, так как она весьма удобна при просмотре текста программы.

      1.8.5. Реализация. С точки зрения пользователя приведенное решение задачи оформления варианта выглядит относительно несложно и довольно-таки привлекательно. Однако судьбу той или иной программной конструкции пока еще чаще определяет не пользователь, а разработчик средств ее системной поддержки. Разработчик же оценивает не только простоту и удобство предлагаемой конструкции, но и трудоемкость ее реализации. Из-за последнего обстоятельства данная конструкция, к сожалению, может и не вызвать энтузиазма: реализация тут потребует серьезных усилий, поскольку она, как легко видеть, пронизывает практически все компоненты операционной среды.
      Так, редактор должен предоставлять возможность выделения и просмотра вариантных фрагментов. Препроцессор или транслятор — возможность осуществлять сборку текста компилируемой программы в соответствии с указаниями назначений. В файловой системе или в ином хранилище исходных текстов программ появляется новый специфический тип объектов — вариантный фрагмент. Кроме того, если понадобится экономить время трансляции, то, вероятно, придется организовывать совместное хранение семейства объектных модулей, получающихся в результате трансляции одного и того же исходного текста программы, но с разным наполнением содержащихся в нем вариантных гнезд.
      Теперь становится понятным, почему подобные специализированные средства традиционно отсутствуют в среде штатного системного программного обеспечения. По-видимому, потребность среднестатистического программиста в подобающем оформлении вариантов не настолько велика, чтобы стимулировать столь серьезные усилия по реализации системной поддержки такого оформления. Кроме того, не в пользу реализации подобного аппарата говорит и некоторое усложнение понятийного базиса операционной среды.
      Однако немало аргументов можно привести и в защиту специализированных средств. Так, сфера применения аппарата оформления варианта не ограничивается конструированием программ, его с успехом можно распространить и на подготовку текстовых документов. В этой области типичной является сходная с программными вариантами ситуация, когда существует шаблон документа, в гнезда которого надо подставлять различные тексты из фиксированного набора. Выигрыш от совместного решения задач оформления вариантов программ и документов очевиден. При тех же практически затратах на реализацию мы не только охватываем поддержкой вариантов сразу две важные области, но и добиваемся унификации пользовательской среды.
      Нельзя забывать и о том, что круг задач расширяемого программирования далеко не замыкается на рассмотренном в настоящей главе оформлении варианта — он несравнимо шире. В книге будет рассмотрен целый ряд полезных для расширяемых программ конструкций, каждая из которых вправе претендовать на собственные средства поддержки. При их реализации возникают, как правило, проблемы, сходные с проблемами реализации варианта. Изолированная реализация отдельной конструкции из этого ряда обычно достаточно трудоемка, но после того как реализована хотя бы одна конструкция, трудоемкость реализации последующих резко падает. Поэтому при создании мало-мальски представительного набора специализированных средств поддержки расширяемости удельные затраты на одну конструкцию могут оказаться вполне приемлемыми.
      Наконец, существуют области, где львиная доля рабочего времени программиста уходит на формирование расширяемых конфигураций и управление ими. Такой областью являются, в частности, задачи вычислительного эксперимента, которым посвящена гл. 4. Тут уже не возникает никаких сомнений в целесообразности разработки специализированных системных средств, поскольку их применение нередко позволяет на порядок повысить производительность программирования.
      Вместе с тем не следует думать, что отсутствие доступных средств системной поддержки обесценивает изучение проблем расширяемости программ. Подобно тому как знание современных алгоритмических языков помогает нам даже при программировании в коде машины, знакомство с наиболее продуктивными расширяемыми конструкциями может оказать существенную помощь при проектировании программ и в традиционной операционной среде, не поддерживающей такие конструкции.

*     *     *

      Итак, в настоящей главе была подробно рассмотрена достаточно известная задача — оформление варианта, благодаря которой первоначальное знакомство с проблематикой расширяемых программ можно считать состоявшимся. Перейдем теперь к более систематическому изучению основных понятий этой области.

Далее

Рейтинг@Mail.ru