Стили и методы программирования

         

Что нужно для переиспользования


Стиль от переиспользования характеризуется тем, что при составлении программы стремятся максимально использовать то, что уже сделано - самим программистом, его коллегами или же вообще где-либо. Давно уже общепризнано, что в идеале на смену программированию как кодированию алгоритмов должно прийти программирование как сборка из заранее заготовленных блоков - сборочное программирование. Этот термин введен в 1978 г. Г. С. Цейтин позднее отделил это понятие от теоретических рассмотрений и представил его с программистской стороны. Заметим, что математики уже давно отказались от построения новых теорем (соответствующих в информатике программам) и новых понятий (соответствующих абстрактным типам данных) с пустого места. В математике весьма профессионально переиспользуются ранее полученные результаты. Здесь из-за концептуального единства системы понятий и строгих критериев обоснованности не возникает проблемы совместимости новых версий, которая зачастую губит попытки не только переиспользования, но и просто использования старых программ1).

Понятно, что при использовании готовых строительных блоков возможны потери. Тем не менее потенциальная выгода за счет переиспользования просто колоссальна. В математике, где имеются точные оценки, показано, что длину доказательства (читай - программы) можно сократить в БАШНЮ ЭКСПОНЕНТ РАЗ без существенной потери эффективности лишь за счет введения лемм (читай - использования уже построенных программ).

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


Вторая ситуация - другая крайность. Программисту на Java потребовалось построить синтаксический анализ. На вопрос о том, как он это делает, получен ответ: "Зачем это знать? У меня есть пакет JavaCC, который все делает, как надо!" Вместе с тем, дальнейшие расспросы показали, что этот программист не представляет себе даже того, какого типа метод анализа поддерживает JavaCC, и, следовательно, ничего не может сказать о том, как задание грамматики для данного пакета связано с эффективностью анализа. Узнав возможные варианты, программист призадумался, но ничего менять не стал. Почему? Ответ простой: "Так ведь все уже работает!" Короче говоря, качество использования готовых компонентов системы зависит от знания о них.

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

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

Расшифровка предыдущего предложения позволит вдумчивому читателю самому вывести все условия, необходимые для обеспечения переиспользования в конкретной обстановке. Любые указания здесь бесполезны (если человек еще не осознал предыдущее) либо вредны (если он думает, что осознал, на самом деле ничего не понимая).


Можно дать лишь общий совет для тех, кто еще занимается (само)образованием.

В математике для программиста важны не столько конкретные результаты (за ними можно обратиться и к справочной литературе), сколько структура понятий и доказательств, способы введения абстракций и применения исключительно абстрактных понятий в частных ситуациях.

Иногда переиспользованию способствует применение развитых языковых средств. В частности, C++ и Java довольно часто позволяют переносить программы из одной операционной обстановки в другую (перенос - одна из форм переиспользования). Но те, кто реально занимался переносом программ, наверняка вспомнят при чтении предыдущего предложения досадные несоответствия, выявлению и предупреждению которых C++ и Java никак не помогают.

Переиспользованию способствует повышение уровня понятий языка, хотя бы до второго-третьего типа (объектная ориентированность языка). Иногда ООП помогает также возможностями наследования свойств и методов объектов (но часто в самых критических ситуациях плохо продуманная концепция наследования столь же сильно и мешает).

Все это - зародыши поддержки стиля программирования, нацеленного на переиспользование. Но в основном сложившаяся практика в значительной степени препятствует переиспользованию, а уровень систем поддержки еще недостаточно высок и неадекватен общей задаче применения данного стиля.

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

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

Применение переиспользуемых компонентов характеризуется следующими особенностями стиля:

  • главная характеристика стиля от переиспользования: предпочтение поиска кандидатов на внедрение в программу их самостоятельной разработке;
  • стремление к исследованию существующих кандидатов, к выявлению в них особенностей, полезных или вредных для решаемой задачи;
  • попытки адаптации своего решения для осуществимости внедрения (в частности, некоторые из паттернов (см.


    ниже) рассматривают именно те случаи, когда структуры данных Вашей программы и переиспользуемого компонента существенно различаются);
  • сопоставление и оценка вариантов внедрения и самостоятельной гипотетической разработки;
  • адаптация внедряемого в программу материала, если она требуется, что возможно лишь при двух условиях:
    • открытость программного текста;
    • наличие адекватной и открытой высокоуровневой документации к этому тексту - без нее текст программы полезен лишь для хакеров.




При разработке переиспользуемых компонентов необходимо учитывать, что подобная разработка всегда требует дополнительных затрат, которые связаны со следующими требованиями:

  • необходимо уделять особое внимание документированию (лучше всего, самодокументированию) переиспользуемых компонентов, причем документация должна четко выделять существенные особенности алгоритма, показывать имеющиеся призраки и использованные подпорки, таким образом, она должна быть не комментарием к тексту программы, а высокоуровневым описанием идеи и того, что оказалось необходимым для ее конкретной реализации;
  • требуется серьезный анализ того, что кандидаты на переиспользование могут быть отнесены к типовым приемам программирования, т.е. имеют достаточно широкую для использования в дальнейшем область применимости2);
  • нужно прорабатывать не только варианты полного переиспользования компонентов as is, но и частичного их переиспользования в виде шаблонов, готовых фрагментов и т. п., когда требуется настройка компонента;
  • необходимы спецификации как области адекватного применения компонента, так и границ применимости (вторая часть почти всегда отсутствует в нынешних спецификациях);
  • в спецификациях нужно четко отличать принципиальные моменты от подпорок и выделять призраки;
  • необходима оценка эффективности применения компонента;
  • необходима специальная забота о публикации компонента для потенциальных пользователей: они должны иметь возможность услышать о нем.



Содержание раздела