Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Пути ограничения сложности программного обеспечения



Способ управления сложными системами был известен еще в древности – «разделяй и властвуй». Поэтому первый способ преодоления сложности ПО – декомпозиция.

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

Существует 2 способа декомпозиции: алгоритмическая декомпозиция и объектно-ориентированная декомпозиция.

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

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

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

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

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

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

 Эволюция технологий программирования

С момента появления первых компьютеров разработка программного обеспечения прошла большой путь от простейших программ на машинном языке до осознания того, что именно технология разработки ПО определяет прогресс в вычислительной технике. По мере совершенствования аппаратуры возрастало значение ПО. Важнейший прорыв произошел в конце 50-х годов, когда появились языки программирования высокого уровня (Фортран, Алгол и др.). Появление этих языков было вызвано тем, что написание программ без них становилось все более сложной задачей. Эти языки ускорили и упростили процесс программирования и существенно расширили круг задач, которые стали решаться с помощью ЭВМ. Новые более сложные задачи, привели к тому, что имеющихся средств снова стало недостаточно для их решения.

Таким образом, каждое новое достижение в аппаратном либо в программном обеспечении приводит к попыткам расширить сферу применения ЭВМ, тем самым ставит новые задачи, для решения которых нужны новые возможности.

Языки этого поколения (Фортран, Алгол, PL/1) являются процедурными и поддерживают процедурный стиль программирования. Программа разрабатывается в терминах тех действий, которые она выполняет. Основной единицей программы является процедура (функция). Процедуры вызывают другие процедуры, все вместе они работают по определенному алгоритму, который ведет к решению задачи.

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

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

Применение ЭВМ для решения задач искусственного интел­лекта и обработки текстов привело к созданию функциональных языков, в частности языка Лисп. Функциональное программиро­вание представляет собой подход, при котором алгоритм описывается как алгоритмически вычислимая функция. Описания программ-функций осуществляется в терминах функциональных определений, а основной операцией, ре6ализующей вычисления функциональной программы, является применение функции к аргументу.

Были разработаны также логические языки программирования – для поддержания логического стиля программирования (ПРОЛОГ). Логическое программирование использует точку зрения на алго­ритмы, выработанную в математической логике. Данные логических программ представлены фактами, играющими роль специальных аксиом соответствующей предметной области, а алгоритмы описы­ваются в виде совокупности так называемых правил логического вывода. Таким образом, факты и правила вывода образуют специ­альную логическую теорию. Реализацию вывода в этой логической теории называют машиной (логического) вывода.

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

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

Первой была осознана проблема ошибок. Возник вопрос, можно ли так организовать тестирование и проверку программ, чтобы добиться 100-процентной уверенности в ее правильности? Работы по организации процесса тестирования начали появляться в конце 60-х годов. Примерно к середине 70-х годов были заложены основы организации тестирования, которыми в основном пользуются в настоящее время.

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

Широкого практического применения эта теория не получила по двум причинам:

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

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

Именно поэтому результаты теории доказательств нашли применение в очень ограниченных областях программирования (например, в разработке компиляторов). Для массового программирования они оказались неприменимы.

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

Одной из наиболее широко применяемых методик программи­рования стало структурное программирование, которое поддерживается процедурными языками.

Следствием интенсивных исследований в области методов программирования стало появление большого числа средств автоматизации разработки программ (CASE-средств, Computer Aided Software Engineering). Предполагалось, что после записи задачи на каком-либо высокоуровневом языке эти системы автоматически (или хотя бы с минимальным участием человека) сгенерируют готовую, правильно работающую программу, которая адекватно решает поставленную задачу.

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

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

В 70-е годы была сформулирована модель процесса разработки. Эта модель выделяла несколько фаз процесса: анализ, кодирование, тестирование, внедрение. Каждая последующая ста­дия «вытекает» из предыдущей, поэтому и модель получила назва­ние каскадной.

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

Очередное увеличение сложности решаемых задач и размеров создаваемых программных систем привело к появлению и широкому распрост­ранению объектно-ориентированного подхода к программирования.

 Структурное программирование

Структурное программирование - это первая законченная методология программирования. Структурное программирование оказало огромное влияние на развитие программирования. Этот метод применялся очень широко в практическом программировании и до сих пор не потерял своего значения для определенного класса задач.

Структурный подход базируется на двух основополагающих принципах:

1. использование процедурных языков программирования;

2. последовательная декомпозиция алгоритма решения задачи сверху вниз.

Задача решается применением последовательности действий. На вход программы подаются некоторые данные, программа выполняется и выдает ответ.

После этого начинается последовательное разложение всей задачи на более простые действия.

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

 

Прочитать адрес

Сверить адрес с базой имеющихся адресов

Если результат проверки положителен, напечатать Да,

в противном случае напечатать Нет.

Очевидно, что такая запись один к одному отображается в программе на языке высокого уровня, например на Паскале.

 

program check_address (input, output); var

an_address : Address; begin

read_address(an_address);

if (check_database(an_address)) then

writelnTMIa") ; else

writeln(" HeT");

end

Эта программа использует процедуру read_ address для чтения адреса и процедуру check_ database для сверки прочитанного адреса с информацией в базе данных. Теперь мы можем продол­жить процесс составления программы для процедур следующего уровня: чтение адреса и сверки с базой данных.

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

Программа компонуется с заглушками и может работать. Заглушки позволяют проверить логику верхнего уровня до реализации следующего уровня.

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

 Объектно-ориентированное программирование


Поделиться:



Последнее изменение этой страницы: 2019-03-31; Просмотров: 521; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.021 с.)
Главная | Случайная страница | Обратная связь