Структурное программирование: основные принципы. Объектно-ориентированное программирование

Начало информационного этапа

Развитие человечества все больше и больше наталкивало величайшие умы на мысли об автоматизации некоторых процессов. Начало этапа программирования приписывается по разным источникам нескольким периодам в промежутке от начала 19 до середины 20 веков. За эти десятилетия появилось множество методик написания исходного кода. Каждая из них кардинально отличается своими принципами и идеями. Рассмотрим структурное программирование, появившееся в 70-х годах прошлого столетия.

Немного истории

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

Основные принципы структурного программирования

Рассмотрим подробно основные моменты структурного подхода.

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

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

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

Языки программирования

С разработкой данной методологии стали появляться и развиваться языки программирования. Структурный подход реализуют такие известные из них, как Pascal (Паскаль), C (Си), а также более устаревший - Algol (Алгол).

Эпилог

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

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

1.2. Основные свойства алгоритма.

Для углубления понятия алгоритма выделим и раскроем его основные свойства, вытекающие из определения.

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

  3. Определенность алгоритма.
  4. Это свойство алгоритма означает,что каждая команда алгоритма должна абсолютно однозначно трактоваться и выполняться исполнителем.

  5. Результативность и конечность алгоритма.
  6. Свойство алгоритма, означающее, что алгоритм должен всегда приводить к результату через конечное число шагов.

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

1.3 Базовые алгоритмические структуры.

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

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

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

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

1.4 Правила построения алгоритма задачи.

Можно сформулировать общие правила построения алгоритма задачи:

  1. Выявить исходные данные, результаты, назначить им имена.
  2. Выбрать метод (порядок) решения задачи.
  3. Разбить метод решения задачи на отдельные этапы.
  4. Составить алгоритм выполнения каждого этапа.
  5. Обеспечить выдачу результатов или сообщение об их отсутствии и предусмотреть возможность после любой операции выхода из задачи.

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

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

1. Обеспечить проверку выполнения всех операций алгоритма;
2. Свести количество вычислений к минимуму.

2.1 Нисходящее пошаговое проектирование

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

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

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

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

Лекция 1. Объектно-ориентированное программирование.

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

8.1. Структурный подход в программировании.

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

Другими факторами, влияющими на эволюцию методов проектирования и создания ПП, являются:

Изменение архитектур вычислительных средств (ВС) в интересах повышения
производительности, надежности;

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

Выделяют 5-ть источников сложности программирования:

Решаемая задача;

Язык программирования;

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

Технологический процесс коллективной разработки и создания ПП;

Стремление к универсальности и эффективности алгоритмов и типов данных.

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

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

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

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

Теоретическое оформление структурный подход получил в начале 70-х годов в работах теоретиков и практиков программирования(А.П.Ершова, Э. Йодана, Н.Вирта). Следует отметить появление структурного программирования, в котором нашла определенное отражение идея упорядочивания структуры программы. Структурное программирование ориентирует на составление программ, структура которых близка к «дереву» операторов или блоков. Использование структуры типа «дерево» в качестве своеобразного эталона объясняется тем, что это простая для анализа и реализации структура.

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

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

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

Развитие языков в направлении повышения эффективности составления прикладных программ привело к разделению языков по следующим уровням:

Низкий уровень (машинно-ориентированные языки - языки ассемблера),

Высокий уровень (процедурно-ориентированные языки: FORTRAN , ALGOL ,

PL /1, Pascal ),

Уровень решаемой задачи (проблемно-ориентированные языки - SQL ).

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

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

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

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

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

Язык программирования позволяет описать свойства моделируемых объектов и порядок манипуляции с объектами или порядок их взаимодействия, сообразуясь с условиями решаемой задачи. Первые языки программирования ориентировались на математические объекты, на определенную модель вычислителя. Поэтому они содержали такие конструкции как переменная, константа, функция, формальные и фактические параметры. Программисты представляли свои программы в виде взаимодействующих функций и модулей. Характер программирования был процедурно-ориентированным, поскольку первостепенное внимание уделялось последовательностям действий с данными. Соответственно такие языки программирования, как FORTRAN , PL -1, С называют процедурно-ориентированными.

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

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

Моделируемый объект всегда представляется человеку чем-то единым, целостным, хотя может состоять из частей или других объектов. Целостное представление объекта в виде взаимосвязанной совокупности его свойств или компонентов является базовым принципом объектного подхода.

Объектный подход начал развиваться в программировании с 70-х годов ( Smalltalk , CLOS , Ada ). Эти языки называются объектными . Иерархическая классификация объектов и наследование свойств являются отправными идеями появившегося в 80-х годах объектно-ориентированного подхода. Одной из причин сравнительно медленного становления объектно-ориентированного стиля программирования является его существенное отличие от процедурно-ориентированного стиля.

8.2. Концепции объектно-ориентированного программирования.

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

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

Основным понятием ООП является объект или класс в C++, который можно рассматривать с двух позиций. Во-первых, с позиции предметной области: класс соответствует определенному характерному объекту этой области. Во-вторых, с позиции технологии программирования, реализующей это соответствие: «класс» в ООП - это определенная программная структура, которая обладает тремя важнейшими свойствами:

Инкапсуляции;

Наследования;

Полиморфизма.

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

Объекты и классы.

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

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

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

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

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

Инкапсуляция свойств объектов.

Инкапсуляция («содержание в оболочке») представляет собой объединение и локализацию в рамках объекта, как единого целого, данных и функций, обрабатывающих эти данные. В совокупности они отражают свойства объекта.

В C++ данные класса и объекта называются элементами данных или полями, а функции — методами или элементами-функциями.

Доступ к полям и методам объекта осуществляется через имя объекта и соответствующие имена полей и методов при помощи операций выбора «.» и «->». Это позволяет в максимальной степени изолировать содержание объекта от внешнего окружения, т. е. ограничить и наглядно контролировать доступ к элементам объекта. В результате замена или модификация полей и методов, инкапсулированных в объект, как правило, не влечет за собой плохо контролируемых последствий для программы в целом. При необходимости указания имени объекта в теле описания этого объекта в C++ используется зарезервированное слово this , которое в рамках объекта является специальным синонимом имени объекта - указателем на объект.

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

Можно сказать, что инкапсуляция подразумевает под собой скрытие данных ( data hiding ), что позволяет защитить эти данные.

А теперь определение, которое точно определяет суть инкапсуляции:

Переменные состояния объекта скрыты от внешнего мира. Изменение состояния объекта(его переменных) возможно ТОЛЬКО с помощью его методов(операций).

Почему же это так важно? Этот принцип позволяет защитить переменные состояния объекта от неправильного их использования.

Это существенно ограничивает возможность введения объекта в недопустимое состояние и несанкционированное разрушение этого объекта.

Для иллюстрации приведенного выше постулата рассмотрим пример.

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

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

Именование классов, элементов данных и методов имеет большое значение в ООП. Названия должны либо совпадать с названиями, использующимися в предметной области, либо ясно отражать смысл или назначение (функциональность) именуемого класса, поля или метода. При этом не следует бояться длинных имен - затраты на написание окупятся при отладке и сопровождении продукта. Текст подобной программы становится понятным без особых комментариев. Дополнительным средством доступа к данным и методам является описание элементов классов с помощью спецификаторов private , protected и public , которые определяют три соответствующих уровня доступа к компонентам класса: частные, защищенный и общедоступный.

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

Методы в классе могут быть объявлены как дружественные ( friend ) или виртуальные ( virtual ). Иногда встречается объявление перегружаемых ( overload ) функций.

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

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

Наследование свойств.

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

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

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

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

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

Наследование в ООП позволяет адекватно отражать родственные отношения объектов предметной области. Если класс В обладает всеми свойствами класса А и еще имеет дополнительные свойства, то класс А называется базовым (родительским), а класс В называется наследником класса А. В C++ возможно одиночное (с одним родителем) и множественное (с несколькими родителями) наследование.

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

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

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

Примеры родственных классов: Координаты на экране -> Цветная точка -> Прямая -> Прямоугольник. Здесь направление стрелки указывает порядок наследования свойств классов.

При указании базового (родительского) класса в описании класса в С++ требуется указать ключевое слово public . Указание этого ключевого слова позволит получить свободный доступ ко всем методам класса, как если бы они были описаны в самом производном классе. В противном же случае, мы не сможем получить доступ к методам родительского класса.

Пример описания наследования классов на С++ :

class A

. . . . .

class B: public A

. . . . .

Полиморфизм поведенческих свойств объектов.

Слово полиморфизм имеет греческое происхождение и переводится как "имеющий много форм".

Полиморфизм - это свойство, которое позволяет одно и тоже имя использовать для решения нескольких технически разных задач.

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

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

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

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

Свойство полиморфизма реализуется не только в механизме замещения (перекрытия) одноименных методов при наследовании свойств, но и в механизме виртуализации методов или позднем связывании методов. Если замещение метода реализуется на этапе компиляции (раннее связывание объекта с методом), то замещение объявленного в описании класса виртуальным ( virtual ) происходит на этапе выполнения (позднее связывание).

Сравним два подхода к покупке, к примеру, килограмма апельсинов. В первом случае мы заранее знаем, что нам надо купить 1 кг апельсинов. Поэтому мы берем небольшой пакет, не много, но достаточно денег, чтобы хватило на этот килограмм. Во втором случае, мы, выходя из дома, не знаем что и как много нам надо купить. Поэтому мы берем машину (а вдруг будет много всего и тяжелое), запасаемся пакетами больших и малых размеров и берем как можно больше денег. Едем на рынок и выясняется, что надо купить только 1 кг апельсинов.

Приведенный пример в определенной мере отражает смысл применения раннего и позднего связывания, соответственно. Очевидно, что для данного примера первый вариант оптимален. Во втором случае мы слишком много всего предусмотрели, но нам это не понадобилось. С другой стороны, если по дороге на рынок мы решим, что апельсины нам не нужны и решим купить 10 кг яблок, то в первом случае мы уже не сможем этого сделать. Во втором же случае - легко.

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

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

Виртуальные методы выполняются медленнее, из-за необходимости дополнительных действий по связыванию.

Создание и уничтожение объектов.

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

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

Взаимодействие объектов и сообщения.

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

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

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

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

8.3. Этапы объектно-ориентированного программирования.

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

В процессе программирования в объектно-ориентированном стиле можно выделить следующие этапы:

  1. Определение основных понятий предметной области и соответствующих им классов, имеющих определенные свойства (возможные состояния и действия). Обоснование вариантов создания объектов.
  2. Определение или формулирование принципов взаимодействия классов и взаимодействия объектов в рамках программной системы.
  3. Установление иерархии взаимосвязи свойств родственных классов.
  4. Реализация иерархии классов с помощью механизмов инкапсуляции, наследования и полиморфизма.
  5. Для каждого класса реализация полного набора методов для управления свойствами объектов.

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

Первые три этапа и являются объектно-ориентированным анализом предметной области.

ООП обладает следующими достоинствами :

Использование более естественных понятий и имен из повседневной жизни или предметной области;

Простота введения новых понятий на основе старых;

Отображение в библиотеке классов наиболее общих свойств и отношений между объектами моделируемой предметной области;

Естественность отображения пространства решаемой задачи в пространство объектов программы;

Простота внесения изменений в классы, объекты и программу в целом;

Полиморфизм классов упрощает составление и понимание программ;

Локализация свойств и поведения на основе инкапсуляции и разграничения доступа упрощают понимание структуры программы и ее отладку;

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

В качестве недостатков ООП можно отметить следующие:

Снижение быстродействия программ, особенно при использовании виртуальных методов;

Большие затраты времени на разработку библиотеки классов, поэтому ООП це-лесообразно при создании больших программ, а не при написании маленьких единичных программ;

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

Целесообразность применения технологии ООП для создания конкретной программной системы определяется двумя главными факторами :

Спецификой предметной области и решаемой прикладной задачи;

Особенностями используемого языка программирования (транслятора).

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

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

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Курсовая работа

Модульный, структурный и объективный подходы к проектированию и программированию

Введение

2.1.2 Структурный подход

2.2.2 Модульный подход

Заключение

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

Введение

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

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

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

А между тем эволюция программного обеспечения, эволюция компьютеров, со всей очевидностью свидетельствует о том, что именно в этой сфере наиболее ярко проявляются законы эволюции, законы иерархии. Предшествующее поколение программистов обучалось программированию непосредственно программированием. Программисты мыслили абстрактными категориями (машинными двоичными кодами). Пользователь получал результат, не зная хода (пути) решения задачи. Выход из тупика вначале был найден на пути структурного (модульного) программирования, при котором задача расчленялась на блоки (модули), из которых потом складывалась та или иная программа. Формировались библиотеки стандартных программ, из которых, как из кирпичиков, строились другие программы. Здесь уже начал возникать совершенно новый механизм (в программировании, но не в математике и др. науках), при котором на некоторый стандартный набор кирпичиков отражалось бесконечное число пространственных «образов». Последовательное прохождение дерева конкретного «образа» программы, с использованием некоторого набора конкретных базисных элементов, приводило к получению конкретного результата. В программировании стал развиваться естественный механизм, который по своим возможностям можно сравнить, пожалуй, только с мозгом человека. При этом одни и те же кирпичики могли использоваться многократно, не только в рамках одного образа, но и при создании других компьютерных образов. Сами же кирпичики являлись листьями конкретных «образов». При этом, чем сложнее сеть деревьев с образами, тем сильнее будут возможности находить и определять «аналогичные» образы, тем больше у компьютера будет «интеллектуальных» возможностей.

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

Рассмотреть различные подходы программирования и проектирования;

Применить каждый из подходов при реализации прикладной задачи.

1. Технологии и парадигмы программирования

1.1 Эволюция парадигмы программирования

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

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

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

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

Оператор_1:

Оператор_2:

Обычно при первом знакомстве с концепциями программирования приходиться сталкиваются именно с этой моделью, и многие широко распространенные языки поддерживают именно ее (например, С, C++, FORTRAN, ALGOL, PL/I, Pascal, Ada, Smalltalk и COBOL).

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

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

Функция_n (... функция_2 (функция_1 (данные))...)

Такую модель поддерживают такие языки как ML и LISP.

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

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

разрешающее условие_1 --> действие_1 разрешающее условие_2 --> действие__2

разрешающее условие_n --> действие _n

Иногда правила записываются в виде «действие if разрешающее условие», когда выполняемое действие записывается слева.

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

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

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

Теория первичных программ была предложена Маддуксом в качестве обобщения методологии структурного программирования для определения однозначной иерархической декомпозиции блок-схем. В этой теории предполагается, что графы программ могут содержать три класса узлов (рисунок 1):

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

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

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

Рисунок 1 Узлы на графе программы

Любая блок-схема состоит только из этих трех компонентов.

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

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

2. Эволюция подходов к проектированию и программированию

2.1 Структурный подход к проектированию и программированию

2.1.1 Понятие структурного программирования

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

Рисунок 2 Типичная блок-схема программы 60-х годов

60-е годы прошлого столетия характеризуются как период «стихийного» программирования. В этот период отсутствовало понятие структуры программы, типов данных и т.д. Вследствие этого код получался запутанным, противоречивым. Программирование тех лет считалось искусством. Конец 60-х - кризис в программирование.

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

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

Структурное программирование - подход, при котором для передачи управления в программе используются только три конструкции, допускающих последовательную, условную и итеративную передачи управления.

При этом безусловная передача управления, например, оператором goto запрещается.

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

Рисунок 3 Блок-схема программы структурированной конструкции

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

2.1.2 Структурный подход

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

а) повышение производительности труда программистов при написании и контроле программ;

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

в) создание программ коллективом разработчиков;

г) окончание создания программ в заданный срок.

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

Концепция структурного программирования предполагает разбиение программы на отдельные компоненты согласно принципу утаивания информации.

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

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

Идентификатором называется строка символов, используемая для идентификации или именованная (последовательность букв, цифр и знаков подчеркивания, которая начинается с буквы или символа подчеркивания и не содержит пробелов).

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

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

а) действуют все идентификаторы, определенные внутри процедуры/функции;

б) действуют все идентификаторы окружающего контекста, если их имена отличаются от имен, объявленных внутри процедуры/функции;

в) локальные идентификаторы процедуры/функции во внешнем окружении не действуют никогда;

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

2.1.3 Методы структурного проектирования

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

а) решения частных задач приводят к решению общей задачи;

б) данная последовательность отдельных действий наиболее рациональна;

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

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

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

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

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

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

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

Поддержка принципов структурного проектирования была заложена в основу так называемых процедурных языков программирования. Как правило, они включали основные «структурные» операторы передачи управления, поддерживали вложение подпрограмм, локализацию и ограничение области «видимости» данных. Среди наиболее известных языков этой группы стоит назвать PL/1, ALGOL-68, Pascal, С.

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

2.2 Модульный подход к проектированию и программированию

2.2.1 Понятие модульного программирования

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

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

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

Структура модуля в терминах языка Pascal.

Модуль (unit) - программная единица, текст которой компилируется независимо (автономно).

Модуль содержит 4 раздела: заголовок, интерфейсная часть (раздел объявлений), раздел реализации и раздел инициализации.

UNIT <имя модуля>; {заголовок}

INTERFACE {интерфейсная часть}

Uses <используемые модули>;

Const <объявления глобальных констант>;

Type <объявления глобальных типов>;

Var <описание глобальных переменных>;

Procedure <заголовки(!) доступных процедур>;

Function <заголовки(!) доступных функций>;

IMPLEMENTATION {раздел реализации}

Uses <используемые при реализации модули>;

Const <объявления скрытых (локальных) констант>;

Type <объявления скрытых (локальных) типов>;

Var <описание скрытых (локальных) переменных>;

Procedure <тела(!) скрытых (локальных) процедур>;

Function <тела(!) скрытых (локальных) функций>;

<основной блок модуля = раздел инициализации>

2.2.2 Модульный подход

Концепцию модульного подхода можно сформулировать в виде нескольких понятий и положений:

а) большие задачи разбиваются на ряд более мелких, функционально самостоятельных подзадач - модулей, которые связаны между собой только по входным и выходным данным;

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

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

г) исходный текст модуля должен иметь заголовок и интерфейсную часть, где отражаются назначение модуля и все его внешние связи;

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

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

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

Модульное проектирование предполагает выделение групп подпрограмм, использующих одни и те же глобальные данные, в отдельно компилируемые модули (библиотеки подпрограмм), например, модуль графических ресурсов. Связи между модулями при использовании данной технологии осуществляются через специальный интерфейс, в то время как доступ к реализации модуля (телам подпрограмм и некоторым «внутренним» переменным) запрещен. Эту технологию поддерживают современные версии языков Pascal и С (C++), языки Ада и Modula.

2.3 Объектный подход к проектированию и программированию

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

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

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

Объект, как логическая единица, содержит следующие данные и операции (методы с кодом алгоритма) в отдельном участке памяти:

а) поля объекта (или атрибуты исходных данных), значения которых определяют текущее состояние объекта;

б) методы объекта, которые реализуют действия (выполнение алгоритмов) в ответ на их вызов в виде преданного сообщения;

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

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

Объекты в программах воспроизводят все оттенки явлений реального мира: «рождаются» и «умирают»; меняют свое состояние; запускают и останавливают процессы; «убивают» и «возрождают» другие объекты.

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

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

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

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

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

Принцип инкапсуляции использовался в технологии модульного программирования. В модуле в явной форме введена инкапсуляция путем разделения его на секции интерфейса и реализации.

В объектно-ориентированном программировании принцип инкапсуляции используется для изоляции класса от остальных частей программы, чтобы сделать его самодостаточным для решения конкретной задачи. Например, класс TForm в среде Delphi содержит (инкапсулирует в себе) все необходимое для создания Windows-окна, класс TMemo представляет собой полнофункциональный текстовый редактор, класс TTimer обеспечивает работу программы с таймером и т.д.

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

TMyClass = class

IntField: Integer;

function MyFunc(a: Integer): Integer;

procedure MyProc; end;

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

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

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

Принцип наследования оперирует с понятиями «предок - потомок» и предусматривает расширение набора свойств наследника за счет принятия всех свойств предка.

Любой класс может быть порожден от другого класса. Для этого при его объявлении указывается имя класса-родителя:

TChildCIass = class (TParentClass)

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

Все классы в Object Pascal порождены от единственного родителя - класса TObject. Этот класс не имеет полей и свойств, но включает в себя методы самого общего назначения, обеспечивающие весь жизненный цикл любых объектов - от их создания до уничтожения. Поэтому программист не может создать класс, который не был бы дочерним классом TObject. Следующие два объявления идентичны.

TaClass = class(TObject) <==> TaClass = class

Принцип наследования приводит к созданию ветвящегося дерева классов. Каждый потомок дополняет возможности своего родителя новыми и передает их своим потомкам. Например, класс TPersistent обогащает возможности своего родителя TObject тем, что он умеет сохранять данные в файле и получать их из него, в результате это умеют делать и все его потомки. Класс TComponent, в свою очередь, умеет взаимодействовать со средой разработчика и передает это умение своим потомкам. TControl не только способен работать с файлами и средой разработчика, но он еще умеет создавать и обслуживать видимые на экране изображения, а его потомок TWinControl может создавать Windows-окна и т.д.

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

Полиморфизм - это средство для придания различных значений одному и тому же событию в зависимости от типа обрабатываемых данных. Этот принцип определяет различные формы реализации одноименного действия.

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

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

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

Кроме этого, в Object Pascal полиморфизм достигается не только механизмом наследования и перекрытия методов родителя, но и их виртуализацией, позволяющей родительским методам обращаться к методам своих потомков

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

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

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

3. Применение различных подходов при решении задач

Рассмотрим, как будет выглядеть программная реализация с использованием различных подходов при решении задачи: Поменять первую и последнюю цифру в натуральном числе. Язык реализации Pascal.

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

program Perestanovka;

N, copy_N, number, copy_number, first, last, stepen, new_N: integer;

{тело программы}

{ввод числа}

write("input N=");

{подсчет количества цифр в числе}

number:=number+1;

copy_N:=copy_N div 10;

if copy_N<>0 then

if number=0 then

{вычисление степени числа 10^(number-1)}

copy_number:=number;

{выделение первой и последней цифры}

copy_N:=copy_N div 10;

copy_number:=copy_number-1;

if copy_number<>1 then

copy_number:=number;

{перестановка цифр}

stepen:=stepen*10;

copy_number:=copy_number-1;

if copy_number>1 then

new_N:=N-first*stepen+last*stepen-last+first;

{вывод результата}

Код линейный, все действия выполняются последовательно, передача управления осуществляется за счет использования оператора перехода goto.

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

program Perestanovka;

{раздел объявления переменных}

N, number, new_N: integer;

{раздел объявления процедур и функций}

{процедура подсчета количества цифр в числе}

while NN<>0 do

{функция определения первой цифры числа}

while kol<>1 do

first_cifra:=NN;

{функция определения последней цифры числа}

last_cifra:=NN mod 10;

{функция возведения целого числа в целую степень}

while pokaz<>0 do

{тело программы}

write("input N=");

kol_cifr(number,N);

if number<>0 then

new_N:=N-first_cifra(N,number)*stepen(10,number-1)+

last_cifra(N)*stepen(10,number-1)-

last_cifra(N)+first_cifra(N,number)

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

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

Program perestanovka;

number: integer;

procedure input;

procedure output;

procedure kol_cifr(var kol: integer; NN: integer);

procedure perestavka(var NN: integer; cf, cl: integer);

function first_cifra(NN: integer; kol: integer): integer;

function last_cifra(NN: integer): integer;

function stepen(bas: integer; pokaz: integer): integer;

while pokaz<>0 do

procedure tN.input;

write(`input N=");

readln(N.znach);

procedure tN.kol_cifr(var kol: integer; NN: integer);

while NN<>0 do

function tN.first_cifra(NN: integer; kol: integer): integer;

while kol<>1 do

first_cifra:=NN;

function tN.last_cifra(NN: integer): integer;

last_cifra:=NN mod 10;

procedure tN.perestanovka(var NN: integer; cf, cl: integer);

NN:=NN-cf*stepen(10,number-1)+cl*stepen(10,number-1)-cl+cf;

procedure tN.output;

Form1.Edit1.Clear;

Form1.Edit1.Text:=inttostr(N.znach);

N.kol_cifr(N.number,N.znach);

if N.number<>0 then

N.perestanovka(N.znach,N.first_cifra(N.znach,N.number),N.last_cifra(N.znach));

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

Заключение

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

Показаны на примерах, как происходит программная реализации при применении того или иного подхода.

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

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

Список использованных источников

1. Буч, Г. Объектно-ориентированный анализ и проектирование с примерами на С++ / Г. Буч, перевод с англ. под ред. И. Романовского и Ф. Андреева. - М.: Вильямс, 2008. - 721 с.

2. Архангельский, А.Я. Программирование в Delphi 7 / А.Я. Архангельский. М.: ООО «Бином-Пресс», 2003. - 1152 с.

3. Программирование. Лекции по программированию. - Режим доступа www.studifi.ru

4. Технология программирования. Структурное и объектно-ориентированное. - Режим доступа www.sgm.forumssity.ru

5. Технология структурного программирования. . - Режим доступа www.razlib.ru

6. On-line Информатика. Модульное программирование. - Режим доступа www.online-ane.ru.

Размещено на Allbest.ru

...

Подобные документы

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

    дипломная работа , добавлен 28.08.2014

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

    дипломная работа , добавлен 04.06.2009

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

    курсовая работа , добавлен 27.11.2012

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

    реферат , добавлен 18.02.2009

    Описание САПР "Ассоль" - модульного программного комплекса, который позволяет по эскизу, фотографии или образцу быстро и точно разработать лекала моделей любой сложности. Комбинаторный синтез технического эскиза. Сфера применения "Ассоль-Дизайн".

    учебное пособие , добавлен 07.02.2016

    Склад атмосферной сушки. Техническая характеристика сушильной камеры "Интер–Урал". Основные требования к проектированию цеха. Технологический процесс изготовления изделий из пиломатериалов. Производственная программа деревоперерабатывающего цеха.

    курсовая работа , добавлен 13.07.2015

    Оптимизация решения на моделях нелинейного программирования. Решение задачи линейного программирования графическим методом. Разработка раскроя древесно-стружечных плит на заготовки. Затраты времени на обработку деталей. Обоснование решений на моделях СПУ.

    курсовая работа , добавлен 17.05.2012

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

    презентация , добавлен 09.12.2015

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

    реферат , добавлен 18.02.2009

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

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

Характерными принципами структурного программирования являются:

· нисходящее программирование – способ разработки программ, при котором программи­рование ведется методом «сверху-вниз», от общего к деталям;

· модульное программирование , при котором относительно независимые подзадачи про­граммируются в виде отдельных программных модулей;

· использование при программировании трех структур управления (следование, выбор, повторение). Структура следование предполагает естественную последовательность выполнения операторов. Структура выбор задается схемой «если – то – иначе» (условный оператор if). Структуре повторения сопоставлен оператор цикла;

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

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

Следование– это линейная последовательность действий (рис. 2.6):

Рис. 2.6. Следование

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

Ветвление алгоритмическая альтернатива. Управление передается одному из двух блоков в зависимости от истинности или ложности условия. Затем происходит выход на общее продолжение (рис. 2.7):

Рис. 2.7. Ветвление

Цикл повторение некоторой группы действий по условию. Различаются два типа цикла. Первый цикл с предусловием (рис. 2.8):

Рис. 2.8. Цикл с предусловием

Пока условие истинно, выполняется серия, образующая тело цикла.

Второй тип циклической структуры цикл с постусловием (рис. 2.9):

Рис. 2.9. Цикл с постусловием

Здесь тело цикла предшествует условию цикла. Тело цикла повторяет свое выполнение, если условие ложно. Повторение кончается, когда условие станет истинным.

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

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

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

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

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

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

Конструкции одного уровня вложенности записываются на одном вертикальном уровне (начинаются с одной позиции в строке);

Вложенная конструкция записывается смещенной по строке на несколько позиций вправо относительно внешней для нее конструкции.

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

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

«сверху вниз»: сначала строится основной алгоритм, затем вспомогательные алгоритмы;

«снизу вверх»: сначала составляются вспомогательные алгоритмы, затем основной.

Первый подход еще называют методом последовательной детализации, второй сборочным методом.

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

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

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

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