Парадигмы программирования

Разработка программ

Разбить на страницы
Показывать лекцию целиком

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

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

Динамика представлений программ

Рассматривая программы и программные системы как формы представления знаний, трудно удержаться от попытки исследования динамики представления знаний на основе аналогии с развитием программ и программных систем.

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

Успешность деятельности ограничена "пропускной способностью" поля зрения. Это ограничение систематически преодолевается посредством обобщения, приводящего к представлениям более высокого порядка - представлениям более мощным, более организованным, например, к процедурам, функциям, фреймам, шаблонам, макросам. Последовательность шагов обобщения можно называть индуктивным развитием представления знаний. В методике программирования индуктивное развитие соответствует восходящим методам, "снизу вверх". Как правило, индуктивное развитие имеет некоторые пределы. Такие пределы при возрастании меры информативности используемых средств рассматриваются Д. Скоттом []. Интересен случай, когда пределом является теория, достаточная для порождения всей достоверной информации, установленной на данный момент времени. При разработке программ роль такого предела играет система программирования.

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

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

Независимо осуществляемое развитие приводит к задаче установления эквивалентности между различными системами представления знаний. При решении этой задачи возникают предпосылки для выравнивания потенциала систем (вводятся недостающие понятия, выполняются аналогичные построения, реализуются подобные инструменты). Таким образом, выделено четыре типа переходов: индуктивное и дедуктивное развитие, конкретизация и выравнивание. Эта классификация сопоставима с классификацией трансформаций программ в теории смешанных вычислений, предложенной А.П. Ершовым. []

Теоретический каркас

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

Аналогично, такие структуры как списки, выстроены над атомами, не разлагаемыми на компоненты, и пустого списка NIL, посредством операции CONS - консолидации. Над списками определены операции, позволяющие разбирать структуры на компоненты, сравнивать и анализировать структуры, отличать атомы от структур и пустой список от других данных. Элементарные операции подчинены аксиомам, обеспечивающим обратимость информационной обработки. Техника программирования на уровне строгих функций поддерживает прозрачность определений и скорость отладки.

Трудоемкость технологий

Устойчивость слабо предсказуемых трудностей программирования достаточно высока. Так, Ф.П. Брукс почти 30 лет назад отмечал неизбежность повторного программирования, морального устаревания результата за время его получения и влияния структуры программистской группы на эффективность трудозатрат. [,] Впечатления от трудного опыта разработки OS IBM 360 Ф. Брукса можно характеризовать следующими цитатами из его знаменитой книги []:

"Система начинает работать как следует только после создания нескольких вариантов, последовавших за первым"

"Неполнота и противоречивость новых идей становится ясной только в процессе реализации"

"На практике оказывается, что все этапы могут начинаться одновременно и проходить параллельно"

"Вторая система - самая опасная из всех, которые проектирует человек"

"Диалоговые интерпретаторы обеспечили наиболее фундаментальные преимущества в отладке"

"Нам не удалось воспитать в программистах походящее отношение к документации"

Логическая ясность идей грамотного программирования Д. Кнута не помогла преодолеть неприязнь программистов к документации [].

При повторном издании (через четверть века!) своей книги [] Ф. Брукс отметил, что основные трудности практического программирования для сложных систем почти не изменились. Современные подходы к разработке ИС скорее являются методами "уклонения от сложностей".

В этом плане отмеченный Бруксом "эффект второй системы" можно избежать погружением разработки первых двух систем на уровень обучения программиста или привлечением напарников, миновавших область действия этого эффекта. []

Технология экстремального программирования нейтрализуют проблему документирования методикой парной разработки. [,]

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

Функциональное программирование и методика рефакторинга ИС нацелены на оттачивание улучшаемых вариантов типовых компонентов, по сложности как правило не превышающих среднюю олимпиадную задачу и требующих на реализацию от полудня до недели. [,]

В начале 70-х годов Дж.М. Вейнберг обратил внимание на частичность понимания целей работы программиста (особенно в сложных проектах), опасность невнимания менеджеров к естественным взаимосвязям в коллективе, разнообразие способностей, необходимых программисту для успешной работы. В основополагающей монографии "Психология программирования" [] Дж. Вейнберг акцентирует внимание на человеческих факторах программирования и показывает, что решение любых сложных проблем начинается с анализа их социально-этической реализуемости. Техническое решение осуществимо, лишь если ясно, кто и почему способен сложную проблему решить.

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

М.М. Леман указывал на возрастание стоимости сопровождения больших программ и объективность эволюции активно используемых программ []. Внимание к завершенности фаз ЖЦ программ помогают четко выделить ближайшую цель, концентрировать усилия на ее достижении и тем самым минимизировать перенос трудозатрат с периода разработки на период сопровождения.

А.Л. Фуксман выделил проблему разложения на модули таких программ, как трансляторы, и обеспечения оперативной обратной связи программирования со сферой приложения программ, предложил методику вертикального сложения программ (на основе функциональной структуры) и проверки частичных результатов в реальной обстановке [].

По мнению Э. Йодена [], истинное предназначение программирования - это трудно выполнимые миссии, т.е. проекты, выполняемые при недостаточных условиях, что активизирует творческий потенциал программистов, заставляет быстро находить эффективные и надежные решения. Эту мысль убедительно подтверждает практика разработки игровых программ. В пользу этого говорит и оценка трудоемкости проектов по классическим схемам ЖЦ программ. Как правило такие оценки завышены во много раз в сравнении с реальными трудозатратами.

Сторонники экстремального программирования (XP) [] выражают претензии программистским авторитетам:

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

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

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

Сторонники функционально-ориентированной разработки (FDD) ИС дорожат накопленным разнообразием языков для передачи информации компьютеру. [] Соглашаясь с Вейнбергом, что программирование - это, прежде всего, уточнение мысленных моделей в партнерах, учитывают и мнение Джефа де Лука: "ИТ - это 80% психологии и 20% технологии". Программирование методом добавления функции за функцией позволяет минимизировать интервал между анализом задачи и тестированием ее частичных решений, что сводит задачу разработки ИС до легко контролируемых задач в рамках поддающегося оценке регулярного процесса. Подобно XP, FDD тяготится составлением рабочих отчетов, которые либо являются неточными, из-за чего становятся бесполезными, либо отбирают у проекта драгоценное время: "Нам платят за результаты а не за отчеты! Красивая презентация означает, что руководители потратили время и средства на нее вместо обеспечения целевых работ".

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

Макеты и прототипы

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

Простейший макет может быть создан из небольшой коллекции тестов, иллюстрирующих поведение программы в наиболее важных точках. Выбор таких точек - необходимая работа, результаты которой многократно используются на всех фазах жизненного цикла программы: при конструировании алгоритмов, автономном тестировании компонентов программы, комплексной отладке программы, демонстрации программы всем заинтересованным лицам, при ее эксплуатации и развитии. Функционирование простых макетов особенно легко реализуется в языках, обладающих унификацией структур данных и функциональных объектов, таких как Lisp и Setl [,].

Setl - язык сверхвысокого уровня, представляет собой попытку активного использования теоретико-множественных понятий в практике программирования [].

Согласно концепции этого языка, понятие "функция" обладает двойственной природой. Функция может быть представлена в алгоритмическом стиле - определением процедуры, выполнение которой сопоставляет результат допустимому аргументу. Но столь же правомерно представление функции в виде графика, отображающего аргументы в результаты. Оба представления могут существовать одновременно - это всего лишь две реализации одной функции. Графическое понимание функции включает в себя и табличную реализацию подобно математическим таблицам Брадиса. Кроме того график функции не обязан быть линией - это может быть фигура произвольных очертаний. Следовательно, аргументу может соответствовать множество результатов, лежащих на пересечении вертикали с этой фигурой - графиком функции. При такой трактовке нет ничего удивительного в постепенном накоплении или построении графика функции. Можно задать небольшое множество точек графика, а потом постепенно его пополнять.

По замыслу Дж. Шварца, автора языка SETL, такая методика может выполнять роль оптимизации особо сложных вычислений.

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

Накопление результатов

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

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

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

Жизненный цикл

Проблема трудоемкости программирования ждет своего решения с давних пор. Ее сложность проявляется по мере накопления опыта обеспечения критических характеристик ИС, таких как надежность и производительность. Полезно совмещение восходящих и нисходящих методов разработки компонентов. Главное - пространство для маневра, возможность согласованного уточнения решений на всех уровнях определения компонентов.

Можно заметить, что основные трудности практического программирования связаны с неполнотой учета структуры ЖЦ программ, а предлагаемые пути являются разными формами наследования успешного опыта. Путь к надежному программированию лежит через достижение многократности использования важных решений, принимаемых на протяжении полного ЖЦ, а не только в процессе программирования [,,,,,,]. Длительность ЖЦ программ зависит от его модели и связана с методами повышения уровня изученности решаемых задач.

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

Практический выбор модели ЖЦ проектируемой программы требует конкретных оценок трудоемкости предлагаемых подходов, ее зависимости от доступной информации и квалификации программистов. Для обоснования таких оценок рассмотрим наиболее типичные особенности процесса разработки ИС и их компонентов. Обычно разработка ИС развивается примерно следующим чередом.

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

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

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

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

    Переход от программ к компонентам позволяет фазы и модели ЖЦ сопоставить с характером изменения информации о компонентах. Такое сопоставление показывает истоки проблем организации разработки ИС. Классическим моделям ЖЦ присущи длинные интервалы локализованного уточнения информации на одном уровне, что затрудняет проверку отношений между уровнями. Подходы XP и FDD позволяют непрерывную проверку таких отношений - всегда существует обратная связь при развитии постановки задачи.

    Исследование моделей ЖЦ компонентов дает перспективу единого подхода к развитию и согласованию разнородной информации о компонентах ИС и решаемых с их помощью задачах. Это может обеспечивать непрерывное согласование процессов разработки и сопровождения ИС.

    Ряд практичных многоязыковых подходов к разработке программ предлагает Uml. [] Хочется отметить следующее:

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

    Страницы:

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

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

    Динамика представлений программ

    Рассматривая программы и программные системы как формы представления знаний, трудно удержаться от попытки исследования динамики представления знаний на основе аналогии с развитием программ и программных систем.

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

    Успешность деятельности ограничена "пропускной способностью" поля зрения. Это ограничение систематически преодолевается посредством обобщения, приводящего к представлениям более высокого порядка - представлениям более мощным, более организованным, например, к процедурам, функциям, фреймам, шаблонам, макросам. Последовательность шагов обобщения можно называть индуктивным развитием представления знаний. В методике программирования индуктивное развитие соответствует восходящим методам, "снизу вверх". Как правило, индуктивное развитие имеет некоторые пределы. Такие пределы при возрастании меры информативности используемых средств рассматриваются Д. Скоттом []. Интересен случай, когда пределом является теория, достаточная для порождения всей достоверной информации, установленной на данный момент времени. При разработке программ роль такого предела играет система программирования.

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

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

    Независимо осуществляемое развитие приводит к задаче установления эквивалентности между различными системами представления знаний. При решении этой задачи возникают предпосылки для выравнивания потенциала систем (вводятся недостающие понятия, выполняются аналогичные построения, реализуются подобные инструменты). Таким образом, выделено четыре типа переходов: индуктивное и дедуктивное развитие, конкретизация и выравнивание. Эта классификация сопоставима с классификацией трансформаций программ в теории смешанных вычислений, предложенной А.П. Ершовым. []

    Теоретический каркас

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

    Аналогично, такие структуры как списки, выстроены над атомами, не разлагаемыми на компоненты, и пустого списка NIL, посредством операции CONS - консолидации. Над списками определены операции, позволяющие разбирать структуры на компоненты, сравнивать и анализировать структуры, отличать атомы от структур и пустой список от других данных. Элементарные операции подчинены аксиомам, обеспечивающим обратимость информационной обработки. Техника программирования на уровне строгих функций поддерживает прозрачность определений и скорость отладки.

    Трудоемкость технологий

    Устойчивость слабо предсказуемых трудностей программирования достаточно высока. Так, Ф.П. Брукс почти 30 лет назад отмечал неизбежность повторного программирования, морального устаревания результата за время его получения и влияния структуры программистской группы на эффективность трудозатрат. [,] Впечатления от трудного опыта разработки OS IBM 360 Ф. Брукса можно характеризовать следующими цитатами из его знаменитой книги []:

    "Система начинает работать как следует только после создания нескольких вариантов, последовавших за первым"

    "Неполнота и противоречивость новых идей становится ясной только в процессе реализации"

    "На практике оказывается, что все этапы могут начинаться одновременно и проходить параллельно"

    "Вторая система - самая опасная из всех, которые проектирует человек"

    "Диалоговые интерпретаторы обеспечили наиболее фундаментальные преимущества в отладке"

    "Нам не удалось воспитать в программистах походящее отношение к документации"

    Логическая ясность идей грамотного программирования Д. Кнута не помогла преодолеть неприязнь программистов к документации [].

    При повторном издании (через четверть века!) своей книги [] Ф. Брукс отметил, что основные трудности практического программирования для сложных систем почти не изменились. Современные подходы к разработке ИС скорее являются методами "уклонения от сложностей".

    В этом плане отмеченный Бруксом "эффект второй системы" можно избежать погружением разработки первых двух систем на уровень обучения программиста или привлечением напарников, миновавших область действия этого эффекта. []

    Технология экстремального программирования нейтрализуют проблему документирования методикой парной разработки. [,]

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

    Функциональное программирование и методика рефакторинга ИС нацелены на оттачивание улучшаемых вариантов типовых компонентов, по сложности как правило не превышающих среднюю олимпиадную задачу и требующих на реализацию от полудня до недели. [,]

    В начале 70-х годов Дж.М. Вейнберг обратил внимание на частичность понимания целей работы программиста (особенно в сложных проектах), опасность невнимания менеджеров к естественным взаимосвязям в коллективе, разнообразие способностей, необходимых программисту для успешной работы. В основополагающей монографии "Психология программирования" [] Дж. Вейнберг акцентирует внимание на человеческих факторах программирования и показывает, что решение любых сложных проблем начинается с анализа их социально-этической реализуемости. Техническое решение осуществимо, лишь если ясно, кто и почему способен сложную проблему решить.

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

    М.М. Леман указывал на возрастание стоимости сопровождения больших программ и объективность эволюции активно используемых программ []. Внимание к завершенности фаз ЖЦ программ помогают четко выделить ближайшую цель, концентрировать усилия на ее достижении и тем самым минимизировать перенос трудозатрат с периода разработки на период сопровождения.

    А.Л. Фуксман выделил проблему разложения на модули таких программ, как трансляторы, и обеспечения оперативной обратной связи программирования со сферой приложения программ, предложил методику вертикального сложения программ (на основе функциональной структуры) и проверки частичных результатов в реальной обстановке [].

    По мнению Э. Йодена [], истинное предназначение программирования - это трудно выполнимые миссии, т.е. проекты, выполняемые при недостаточных условиях, что активизирует творческий потенциал программистов, заставляет быстро находить эффективные и надежные решения. Эту мысль убедительно подтверждает практика разработки игровых программ. В пользу этого говорит и оценка трудоемкости проектов по классическим схемам ЖЦ программ. Как правило такие оценки завышены во много раз в сравнении с реальными трудозатратами.

    Сторонники экстремального программирования (XP) [] выражают претензии программистским авторитетам:

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

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

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

    Сторонники функционально-ориентированной разработки (FDD) ИС дорожат накопленным разнообразием языков для передачи информации компьютеру. [] Соглашаясь с Вейнбергом, что программирование - это, прежде всего, уточнение мысленных моделей в партнерах, учитывают и мнение Джефа де Лука: "ИТ - это 80% психологии и 20% технологии". Программирование методом добавления функции за функцией позволяет минимизировать интервал между анализом задачи и тестированием ее частичных решений, что сводит задачу разработки ИС до легко контролируемых задач в рамках поддающегося оценке регулярного процесса. Подобно XP, FDD тяготится составлением рабочих отчетов, которые либо являются неточными, из-за чего становятся бесполезными, либо отбирают у проекта драгоценное время: "Нам платят за результаты а не за отчеты! Красивая презентация означает, что руководители потратили время и средства на нее вместо обеспечения целевых работ".

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

    Макеты и прототипы

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

    Простейший макет может быть создан из небольшой коллекции тестов, иллюстрирующих поведение программы в наиболее важных точках. Выбор таких точек - необходимая работа, результаты которой многократно используются на всех фазах жизненного цикла программы: при конструировании алгоритмов, автономном тестировании компонентов программы, комплексной отладке программы, демонстрации программы всем заинтересованным лицам, при ее эксплуатации и развитии. Функционирование простых макетов особенно легко реализуется в языках, обладающих унификацией структур данных и функциональных объектов, таких как Lisp и Setl [,].

    Setl - язык сверхвысокого уровня, представляет собой попытку активного использования теоретико-множественных понятий в практике программирования [].

    Согласно концепции этого языка, понятие "функция" обладает двойственной природой. Функция может быть представлена в алгоритмическом стиле - определением процедуры, выполнение которой сопоставляет результат допустимому аргументу. Но столь же правомерно представление функции в виде графика, отображающего аргументы в результаты. Оба представления могут существовать одновременно - это всего лишь две реализации одной функции. Графическое понимание функции включает в себя и табличную реализацию подобно математическим таблицам Брадиса. Кроме того график функции не обязан быть линией - это может быть фигура произвольных очертаний. Следовательно, аргументу может соответствовать множество результатов, лежащих на пересечении вертикали с этой фигурой - графиком функции. При такой трактовке нет ничего удивительного в постепенном накоплении или построении графика функции. Можно задать небольшое множество точек графика, а потом постепенно его пополнять.

    По замыслу Дж. Шварца, автора языка SETL, такая методика может выполнять роль оптимизации особо сложных вычислений.

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

    Накопление результатов

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

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

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

    Жизненный цикл

    Проблема трудоемкости программирования ждет своего решения с давних пор. Ее сложность проявляется по мере накопления опыта обеспечения критических характеристик ИС, таких как надежность и производительность. Полезно совмещение восходящих и нисходящих методов разработки компонентов. Главное - пространство для маневра, возможность согласованного уточнения решений на всех уровнях определения компонентов.

    Можно заметить, что основные трудности практического программирования связаны с неполнотой учета структуры ЖЦ программ, а предлагаемые пути являются разными формами наследования успешного опыта. Путь к надежному программированию лежит через достижение многократности использования важных решений, принимаемых на протяжении полного ЖЦ, а не только в процессе программирования [,,,,,,]. Длительность ЖЦ программ зависит от его модели и связана с методами повышения уровня изученности решаемых задач.

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

    Практический выбор модели ЖЦ проектируемой программы требует конкретных оценок трудоемкости предлагаемых подходов, ее зависимости от доступной информации и квалификации программистов. Для обоснования таких оценок рассмотрим наиболее типичные особенности процесса разработки ИС и их компонентов. Обычно разработка ИС развивается примерно следующим чередом.

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

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

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

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

    Переход от программ к компонентам позволяет фазы и модели ЖЦ сопоставить с характером изменения информации о компонентах. Такое сопоставление показывает истоки проблем организации разработки ИС. Классическим моделям ЖЦ присущи длинные интервалы локализованного уточнения информации на одном уровне, что затрудняет проверку отношений между уровнями. Подходы XP и FDD позволяют непрерывную проверку таких отношений - всегда существует обратная связь при развитии постановки задачи.

    Исследование моделей ЖЦ компонентов дает перспективу единого подхода к развитию и согласованию разнородной информации о компонентах ИС и решаемых с их помощью задачах. Это может обеспечивать непрерывное согласование процессов разработки и сопровождения ИС.

    Ряд практичных многоязыковых подходов к разработке программ предлагает Uml. [] Хочется отметить следующее:

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

    Вернуться к учебному плану