Структурный подход в программировании.
Лекция 1. Объектно-ориентированное программирование.
Объектно-ориентированное программирование (ООП) является доминирующим стилем при создании больших программ. Основные этапы эволюции структурного подхода в программировании помогают лучше понять взаимосвязь структурного подхода, модульного программирования и ООП.
Удельная стоимость создания программ до последнего времени менялась мало. С ростом объема программы удельная стоимость ее создания могла нелинейно возрастать. Время создания сложных программ пропорционально квадрату или даже кубу объема программ. Поэтому одним из основных факторов, определяющих развитие технологии программирования, является снижение стоимости проектирования и создания программных продуктов (ПП) или борьба со сложностью программирования.
Другими факторами, влияющими на эволюцию методов проектирования и создания ПП, являются:
- изменение архитектур вычислительных средств (ВС) в интересах повышения
производительности, надежности;
- упрощение взаимодействия пользователей с ВС и интеллектуализация ВС.
Действие двух последних факторов сопряжено с ростом сложности программного обеспечения ВС. Сложность представляет неотъемлемое свойство программирования и программ, которое проявляется во времени и стоимости создания программ, в объеме или длине текста программы, характеристиках ее логической структуры, задаваемой операторами передачи управления (ветвления, циклы, вызовы подпрограмм).
Выделяют 5-ть источников сложности программирования:
- решаемая задача;
- язык программирования;
- среда выполнения программы;
- технологический процесс коллективной разработки и создания ПП;
- стремление к универсальности и эффективности алгоритмов и типов данных.
От свойства сложности нельзя избавиться, но можно изменять характеристики его проявления путем управления или организации.
В программировании широко используется фундаментальный принцип управления сложными системами, который известен человеку с глубокой древности - devide et impera (разделяй и властвуй, лат.) и применяется при разработке и проектировании любых сложных технических систем. Согласно первой части этого принципа, при проектировании сложной программной системы проводится алгоритмическая декомпозиция решаемой задачи.
Целью декомпозиции является представление разрабатываемой системы в виде взаимодействующих небольших подсистем (модулей или блоков), каждую из которых можно отладить независимо от других. При разработке системы, разделенной на подсистемы, необходимо держать в уме информацию о гораздо меньшем числе деталей, чем в отсутствие такого разделения.
Наряду с термином декомпозиция, также используется термин структуризация проблемы, задачи или программы. Идеи разделения программ на относительно самостоятельные крупные части, реализующие определенные процедуры и функции и образующие определенную иерархию взаимосвязей, нашли отражение в структурном подходе к разработке и созданию программных средств. В программировании структурный подход появился с возникновением первых подпрограмм и функций, написанных в процедурно-ориентированном стиле. Данный стиль опирается на правило: определить переменные и константы, которые понадобится хранить в памяти компьютера и описать алгоритм их обработки.
Теоретическое оформление структурный подход получил в начале 70-х годов в работах теоретиков и практиков программирования(А.П.Ершова, Э. Йодана, Н.Вирта). Следует отметить появление структурного программирования, в котором нашла определенное отражение идея упорядочивания структуры программы. Структурное программирование ориентирует на составление программ, структура которых близка к «дереву» операторов или блоков. Использование структуры типа «дерево» в качестве своеобразного эталона объясняется тем, что это простая для анализа и реализации структура.
Дальнейшее развитие структурного подхода привело к модульному программированию. Оно предусматривает декомпозицию прикладной задачи в виде иерархии взаимодействующих модулей или программ. Модуль, содержащий данные и процедуры их обработки, удобен для автономной разработки и создания. Специализация модулей по видам обработки и наличие в них данных определенных типов - это свойства, которые отражают связь модульного программирования и ООП.
Важнейшими инструментами производителей ПП, в которых находят отражение практически все аспекты эволюции, являются языки программирования.
Язык программирования изначально ориентирован на компьютер и содержит набор типов данных, операторов, операций, функций, которые достаточно просто могут быть переведены в команды по управлению аппаратным и программным обеспечением компьютера. При этом желательно максимизировать эффективность трансляции предложений языка в машинные коды в смысле минимизации требуемой памяти, времени выполнения программы и стоимости создания транслятора. Вместе с тем язык программирования ориентирован на программиста и предоставляет средства для моделирования объектов, их свойств и поведения при решении прикладных задач в некоторой предметной области в виде программ.
Развитие языков в направлении повышения эффективности составления прикладных программ привело к разделению языков по следующим уровням:
- низкий уровень (машинно-ориентированные языки - языки ассемблера),
- высокий уровень (процедурно-ориентированные языки: FORTRAN, ALGOL,
PL/1, Pascal),
- уровень решаемой задачи (проблемно-ориентированные языки - SQL).
Введение типов данных обозначило еще одно направление развития техно-
логии программирования. Типизация данных предназначена как для облегчения
составления программ, так и для автоматизации выявления ошибок использова-
ния данных в виде операндов и фактических параметров при вызове функций.
Использование структурных типов данных позволяет, во-первых, упростить работу алгоритмиста при сопоставлении структур данных прикладной задачи и данных, обрабатываемых функциями программных модулей, и, во-вторых, сократить объем рутинной работы программиста при кодировании алгоритма обработки.
Результатом обобщения понятия «тип данных» являются классы объектов (C++), которые могут содержать в качестве элементов не только данные определенного типа, но и методы их обработки (функции).
Таким образом, по мере развития технологии программирования и в программах, и в типах данных все адекватнее отражалась структура решаемой прикладной задачи и осуществлялась соответствующая интеграция данных и программ в модулях. Одновременно с этим языки программирования пополнились средствами, необходимыми для описания подобных структур. Развитие идей абстрагирования и модульности привело к появлению в программировании объектного подхода.
Человек мыслит образами или объектами, он знает их свойства и манипулирует ими, сообразуясь с определенными событиями. Древним грекам принадлежала мысль о том, что мир можно рассматривать в виде объектов и событий. Люди обычно имеют объектно-ориентированный взгляд на мир. Так, подумав о телефонном аппарате, человек может представить не только его форму и цвет, но и возможность позвонить, характер звучания звонка и ряд других свойств (в зависимости от его технических знаний, фантазии).
Язык программирования позволяет описать свойства моделируемых объектов и порядок манипуляции с объектами или порядок их взаимодействия, сообразуясь с условиями решаемой задачи. Первые языки программирования ориентировались на математические объекты, на определенную модель вычислителя. Поэтому они содержали такие конструкции как переменная, константа, функция, формальные и фактические параметры. Программисты представляли свои программы в виде взаимодействующих функций и модулей. Характер программирования был процедурно-ориентированным, поскольку первостепенное внимание уделялось последовательностям действий с данными. Соответственно такие языки программирования, как FORTRAN, PL-1, С называют процедурно-ориентированными.
Данные и подпрограммы объединялись в модули в соответствии с логикой проектировщиков, создающих сложные программные системы для определенных областей их применения. Логика интеграции в модули определялась рядом факторов, среди которых следует отметить свойства предметной области: данные и подпрограммы их обработки, соответствующие определенному классу объектов предметной области, объединялись в модуль. Так, модуль обработки строк содержал функции выполнения основных операций со строками: объединения, сравнения, копирования, вычисления длины строки.
Развитием идеи модульного программирования является сопоставление объектам предметной области (моделируемым объектам) программных конструкций, называемых объектами, объектными типами или классами (моделирующими объектами). Моделирующие объекты содержат данные и функции, которые описывают свойства моделируемых объектов. Так, данные могут отражать признаковые или количественные свойства (масса, длина, мощность, цена), а функции отражают поведенческие или операционные свойства (изменить массу, вычислить мощность, установить цену). Таким образом, при объектном подходе интеграция данных и функций их обработки определяется структурой предметной области, т.е набором моделируемых объектов, их взаимодействием в рамках решаемой задачи.
Моделируемый объект всегда представляется человеку чем-то единым, целостным, хотя может состоять из частей или других объектов. Целостное представление объекта в виде взаимосвязанной совокупности его свойств или компонентов является базовым принципом объектного подхода.
Объектный подход начал развиваться в программировании с 70-х годов (Smalltalk, CLOS, Ada). Эти языки называются объектными. Иерархическая классификация объектов инаследование свойств являются отправными идеями появившегося в 80-х годах объектно-ориентированного подхода. Одной из причин сравнительно медленного становления объектно-ориентированного стиля программирования является его существенное отличие от процедурно-ориентированного стиля.