Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Мищъ_ ответы.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
561.15 Кб
Скачать

8. Компонентно-ориентированное проектирование и программирование. Пример - модули компиляции и внутренняя структура Ада программ

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

9. Согласованность средств проблемной ориентации в проектных решениях и при разработке на языке программирования

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

Во время разработки любого проекта необходимым действием является регулярное сохранение предыдущих версий файлов (backup) с возможностью быстрого их восстановления. Необходимость в этом возникает, в частности, при поиске причины появления новых ошибок между версиями (bug tracking). Самым простым решением является использование для этих целей мощного архиватора, стримера и т.п., но их работа при больших размерах проекта может растянуться на часы. Более того, часто желательно сохранять каждую версию каждого файла, снабжая ее для избежания путаницы комментарием: кто изменил этот файл и зачем. Для этих целей используются системы контроля версий (Version Control Systems).

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

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

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

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

С точки зрения того, внесены ли в набор понятий особые, специфичные для предметной области объекты, языки делятся на универсальные (процедурные) и специализированные. К последним можно отнести Prolog, Lisp. Универсальные языки позволяют реализовать любой алгоритм, пользуясь стандартным набором конструкций. Благодаря этому, код на таком языке может быть достаточно легко перенесен из одного процедурного языка в другой при помощи консервативных изменений.

Приведем основные концепции, внесенные в те или иные общеупотребительные языки и связанные с ними понятия: - Типизация/структуры данных Любой язык характеризуется набором _базовых типов_, возможностями по пополнению этого набора при помощи ряда _конструкторов_: массив, запись (структура), объединение. В некоторых языках имеется универсальный тип (Variant в Delphi и Visual Basic), свободно используемый как любой из базовых типов. Степень контроля типов может быть очень разной - от полного отсутствия до крайне жесткого. Важно наличие (возможно, в виде библиотеки) структур данных переменной длины, например, динамических массивов. - Подпрограммы и вызовы Различия в языках сводятся к способам определения процедур и функций, вариантам передачи параметров, возможностям определения рекурсивных процедур и наличию процедурного типа данных. - Типы памяти Наличие и широкая классификация типов памяти дает возможность эффективно управлять ее распределением, но и вносит сложность, требующую от программиста более внимательного отношения. Обычно выделяют (максимальный спектр): регистры, глобальные, локальные и динамические переменные. - Модули Наличие средств логического объединения группы процедур/функций/переменных позволяет работать с большими проектами, упрощая их структуру. Важное свойство - возможность описания процедур инициации и завершения модуля. - Объектный подход Объединение структур и методов их обработки (_инкапсуляция_) создает значительные удобства при программировании. Возможность наследования позволяет привести в систему набор структур. Автоматически вызываемые конструкторы и деструкторы упрощают отслеживание взаимосвязей. Все это составляет удобный инструмент для описания понятий и действий прикладной программы. - Переносимость - независимость от аппаратуры, реализуемая при помощи семантики, не зависящей от конкретной машины и внесением в язык ряда специфичных понятий - таких как базовый тип с нефиксированным размером (int в C).

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

Рассмотрим популярные языки и программные среды с точки зрения приспособленности под различные классы задач.

BASIC (Beginner's All-purpose Symbolic Instruction Code) Рожденный в 60-е годы, Бейсик был задуман как простой язык для быстрого освоения. Однако для достижения этого качества был принят ряд решений (отсутствие типизации, нумерация строк и неструктурное GOTO, и др.), негативно сказывающихся на стиле изучающих программирование. Кроме того, недостаток выразительных средств привел к появлению огромного количества диалектов языка, не совместимых между собой. Современные, специализированные версии Бейсика, несмотря на приобретенную "структурность", обладают все теми же недостатками, прежде всего - небрежностью по отношению к типам и описаниям. Пригоден для использования на начальном этапе обучения, как средство автоматизации (в случаях когда он встроен в соответствующие системы) либо как средство для быстрого создания приложений.

Pascal Разработанный известным теоретиком Н.Виртом на основе идей Алгола-68. Предназначался прежде всего для обучения программированию. Построенный по принципу "необходимо и достаточно", он располагает строгим контролем типов, конструкциями для описания произвольных структур данных, небольшим, но достаточным набором операторов структурного программирования. К сожалению, обратной стороной простоты и строгости является громоздкость описаний конструкций языка.

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

C и C++ В основе языка C - требования системного программиста: полный и эффективный доступ ко всем ресурсам компьютера, средства программирования высокого уровня, переносимость программ между различными платформами и операционными системами. С++, сохраняя совместимость с C, вносит возможности объектно-ориентированного программирования, выражая идею класса (объекта) как определяемого пользователем типа. Благодаря перечисленным качествам, C/C++ занял позицию универсального языка для любых задач. Но его применение может стать неэффективным там, где требуется получить готовый к употреблению результат в кратчайшие сроки, либо там, где невыгодным становится сам процедурный подход.

Delphi Его ниша - т.н. быстрое создание приложений (Rapid Application Developing, RAD). Подобные средства позволяют в кратчайшие сроки создать рабочую программу из готовых компонентов, не растрачивая массу усилий на мелочи. Особое место в таких системах занимают возможности работы с базами данных.

Java Как яркий пример специализации, язык Java появился в ответ на потребность в идеально переносимом языке, программы на котором эффективно исполняются на стороне клиента WWW. Ввиду специфики окружения, Java может быть хорошим выбором для системы, построенной на Internet/Intranet технологии.

АДА --гарантируя прозрачность организации ввода-вывода, обеспечивает должную абстракцию алгоритма, абстракцию даных, модульность предлагает понятную нотацию, традиционные типы, включает классический набор операторов, полный набор средств форматирования 1/0 на консоль, обеспечивает средства надёжного программирования. В общем, надёжно поддерживает алгоритмическую мысль

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