Теоретические основы объектно-ориентированного программирования

Применение объектно-ориентированного подхода к проектированию программных продуктов. Особенность исследования основных языков программирования. Главные характеристики продукта Delphi. Исследование масштабируемых средств для построения баз данных.

Рубрика Программирование, компьютеры и кибернетика
Вид лекция
Язык русский
Дата добавления 03.03.2018
Размер файла 96,5 K

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

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

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

ТЕОРЕТИЧЕСКИЕ ОСНОВЫ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ

1. Основные понятия объектно-ориентированного проектирования

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

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

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

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

Состояние объекта определяется перечнем всех возможных (обычно статических) свойств и текущими значениями (обычно динамическими) каждого из этих свойств. Свойства объекта характеризуются значениями его параметров. Поведение объекта описывает, как воздействует на другие объекты или подвергается воздействию со стороны других объектов с точки зрения изменения его собственного состояния и состояния других объектов. Также говорят, что поведение объекта определяется его действиями.[26, 30]

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

- конструктор, создание и инициализация объекта;

- деструктор, разрушающий объект;

- модификатор, изменяющий состояние объекта;

- селектор для доступа к переменным объекта без их изменения;

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

Известна и другая классификация методов объекта, когда выделяют функции управления, реализации, доступа, а также вспомогательные функции.[25]

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

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

Так, отношение использования реализуется посылкой сообщений от объекта A к объекту B. При этом объект A может выступать в роли:

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

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

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

Отношение включения имеет место тогда, когда составной объект содержит другие объекты.

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

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

- включения или составной части (лапа - часть кошки);

- ассоциативности, когда между классами есть сгубо смысловая связь (кошки и собаки - домашние животные).

Объект, обладающий перечисленными характеристиками, в общем случае служит моделью реальной сущности, поскольку при его описании пренебрегают второстепенными или несущественными в конкретной ситуации свойствами.[25,26,27]

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

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

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

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

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

- проведение объектно-ориентированного анализа предметной области;

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

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

Объектно-ориентированный анализ

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

Известны несколько подходов к проведению ООА. Так, в работе С. Шлеер и С. Меллора "Объектно-ориентированный анализ: моделирование мира в состояниях" выделены три этапа ООА:[50]

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

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

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

В работе Г. Буча “Объектно-ориентированное проектирование с примерами применения” отмечаются следующиеальтернативные подходы к ООА:

- Метод неформального описания, в котором выделяются существительные и глаголы в описании предметной области.[27] Существительные здесь рассматриваются в качестве кандидатов для образования классов, а глаголы - как кандидаты в операции над классами;

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

Пример объектно-ориентированного анализа

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

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

- множества данных X;

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

- множества связей по определению R.

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

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

Данные (множество X): множество данных, элемент множества данных.

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

Задачи (множество F): множество задач, элемент множества задач (конкретная задача), набор аргументов (входных и выходных данных задачи), аргумент задачи;

Связи по определению (множество R): множество связей, элемент множества связей, тип связи (старший - младший, функция-предикат);

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

Модули (множество M): множество модулей, элемент множества модулей, список параметров модуля, параметр модуля.

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

Кроме понятий - существительных следует выделить понятия - глаголы (действия), относящиеся к понятиям - существительным. В рассматриваемом примере действиями могут быть:

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

- добавить новый элемент в множество (данных, задач, связей);

- удалить элемент из множества (данных, задач, связей);

- ввести значение элемента множества данных;

- вывести на экран (в файл, на принтер) значение элемента множества данных;

- выполнить задачу.

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

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

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

- имя класса, т.е. присвоенный ему идентификатор;

- множественность экземпляров класса (0/1/n);

- иерархия класса ( базовые классы);

- структура и интерфейс класса.

Здесь под структурой понимаются как атрибуты класса (элементы-данные), так и действия (методы). Данные и методы разбиваются по уровням доступа.

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

Для классов желательно определить жизненные циклы экземпляров класса: когда, при каких условиях создается экземпляр класса, когда изменяется его состояние и когда он уничтожается.[28]

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

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

Например, в рассматриваемом примере процесс определения нового данного должен включать ввод имени данного и его описания, включающего тип данного, уровень агрегирования, границы индексов для массива. После ввода пользователем имени данного нужно проверить, является ли это имя уникальным.[27,28]

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

Процесс объектно-ориентированного проектирования

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

В рассмотренном выше примере были выделены классы “множество данных” и “данное”. Пусть классу “множество данных” присвоено имя TXSet.

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

Чтобы использовать указатели на экземпляры данных как элементы массива, все классы, определяющие типы данных, должны быть образованы из общего базового класса.[27,28]

Пусть требуется обеспечить возможность использования числовых скалярных данных и массивов (векторов и прямоугольных матриц), а также данных типа строк и массива строк. Естественно определить для каждого такого типа свой класс: TDScal, TDArray, TDString, TDStringArray. В каждом из этих классов должно быть поле идентификатора данного ident, поле описания данного head и, возможно, поле flags, представляющее собой набор битов, дополняющих описание данного. Может оказаться удобным иметь и поля, содержащие количество знаков при представлении скаляра или элементов массивов (width) и количество цифр в дробной части для представления чисел (dec). Все эти данные можно объединить в классе TData, базовом для остальных классов данных. Таким образом, вместо одного класса “данное”, выделенного на этапе анализа, появилось пять классов. После этого следует вернуться к этапу анализа и оформить рабочие документы анализа для новых классов.

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

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

Таким образом, процесс объектно-ориентированного проектирования состоит из циклического выполнения четырех основных шагов:[26,27]

- определение классов и объектов на том или ином уровне абстракции;

- выявление семантики классов;

- установление (идентификация) связей между классами и объектами;

- Реализация классов.

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

2. Объектно-ориентированный подход в программировании

Технологии программирования

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

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

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

В 1958 г. были разработаны первые языки программирования, Фортран и Алгол-58. Программа на Фортране состояла из главной программы и некоторого количества процедур - подпрограмм и функций. Программа на Алголе-58 и его последующей версии Алголе-60 представляла собой единое целое, но имела блочную структуру, включающую главный блок и вложенные блоки подпрограмм и функций. Компиляторы для Фортрана обеспечивали раздельную трансляцию процедур и последующее их объединение в рабочую программу, первые компиляторы для Алгола предполагали, что транслируется сразу вся программа, раздельная трансляция процедур не обеспечивалась.[51]

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

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

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

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

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

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

- построением языка программирования, содержащего как можно больше типов данных, и выбором для каждого класса задач некоторого подмножества этого языка. Такой язык иногда называют языком-оболочкой. На роль языка-оболочки претендовал язык ПЛ/1, оказавшийся настолько сложным, что так и не удалось построить его формализованное описание. Отсутствие формализованного описания, однако, не помешало широкому применению ПЛ/1 как в Западной Европе, так и в бывшем СССР;[52]

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

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

Сущность объектно-ориентированного подхода к программированию

Основные идеи объектно-ориентированного подхода опираются на следующие положения:

- программа представляет собой модель некоторого реального процесса, части реального мира;

- модель реального мира или его части может быть описана как совокупность взаимодействующих между собой объектов;

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

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

- объекты, описанные одним и тем же набором параметров и способные выполнять один и тот же набор действий, представляют собой класс однотипных объектов.[25,26,27]

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

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

Классы объектов часто удобно строить так, чтобы они образовывали иерархическую структуру. Например, класс “Студент”, описывающий абстрактного студента, может служить основой для построения классов “Студент 1 курса”, “Студент 2 курса” и т.д., которые обладают всеми свойствами студента вообще и некоторыми дополнительными свойствами, характеризующими студента конкретного курса. При разработке интерфейса с пользователем программы могут использовать объекты общего класса “Окно” и объекты классов специальных окон, например, окон информационных сообщений, окон ввода данных и т.п. В таких иерархических структурах один класс может рассматриваться как базовый для других, производных от него, классов. Объект производного класса обладает всеми свойствами базового класса и некоторыми собственными свойствами, он может реагировать на те же типы сообщений от других объектов, что и объект базового класса, а также на сообщения, имеющие смысл только для производного класса. Обычно говорят, что объект производного класса наследует все свойства своего базового класса.

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

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

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

Наиболее используемыми в настоящее время объектно-ориентированными языками являются Паскаль с объектами, Delphi и Си++, причем наиболее развитые средства для работы с объектами содержатся в Си++.

Практически все объектно-ориентированные языки программирования являются развивающимися языками, их стандарты регулярно уточняются и расширяются. Следствием этого развития являются неизбежные различия во входных языках компиляторов разных систем программирования. Наиболее распространенны в настоящее время это системы программирования Microsoft C++ , Microsoft Visual C++ и системы программирования фирмы Borland International.

3. Объектно-ориентированное мышление и принципы объектно-ориентированного подхода в программировании

Объектно-ориентированное мышление

Объектно-ориентированное программирование (ООП) - основная методология программирования 1990-х годов. Она является продуктом 25 летней практики и включает ряд языков: Simula 67, Smalltalk, Lisp, Clu, Actor, Eiffel, Objective C, Delphi, C++. Это стиль программирования, который фиксирует поведение реального мира таким способом, при котором детали его реализации скрыты.

Почему ООП так популярно:

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

· желание перейти от существующих языков программирования к новой технологии;

· вдохновляющее сходство с идеями, родившимися в других областях.

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

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

ООП является новым пониманием того, что называется вычислениями. Чтобы стать профессионалом в ООП, недостаточно просто добавить новые знания, необходима полная переоценка привычных методов разработки программ.[50,52]

Язык и мышление.

Язык, на котором мы говорим, непосредственно влияет на способ восприятия мира. Это касается не только естественных языков, но и для искусственных языков - языков программирования. Чтобы эффективно использовать ООП, требуется глядеть на мир иным способом, не как с точки зрения структурных языков. Само по себе использование С++ или Delphi не делает программу ООП. "Программа фортрановского типа " может быть написана на любом языке".

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

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

Новая парадигма

ООП часто называют новой парадигмой программирования. Другие парадигмы: директивная (структурное программирование - Pascal, C) и логическая - Prolog, функциональное - Lisp, Effel. Парадигмы в программировании определяют как проводить вычисления, как работа, выполняемая компьютером, должна быть структурирована и организована.
Новички в информатике часто могут освоить парадигму лучше, чем опытные профессионалы, так как этот способ решения задач ближе к естественному восприятию.[26]

Способ видения мира.

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

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

Итак, первым принципом объектно-ориентированного подхода к решению задачи является способ задания действий.[27,52]

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

Сокрытие информации является важным принципом и в традиционных языках программирования. Чем же пересылка сообщения отличается в ООП и в традиционных подходах?

Первое отличие состоит в том, что имеется вполне определенный получатель - агент, которому послано сообщение. При вызове процедуры нет столь явно выделенного получателя. [53]

Второе отличие состоит в том, что интерпретация сообщения (а именно метод, вызываемый после приема сообщения) зависит от получателя и является различной для разных получателей. Вы можете попросить своего товарища, летящего в город, где живут ваши родственники, поздравить их, и метод, который он изберет для решения этого запроса будет отличаться от того, который использовали на почте. Хотя родственники будут поздравлены. Если же Вы попросите коменданта общежития поздравить Ваших родственников, то у нее, вероятно, вообще не найдется метода для решения этой задачи, а если она и примет сообщение, то выдаст диагностическое сообщение об ошибке.[27]

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

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

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

Мы можем рассматривать почту как некоторое средство связи. Объединим в средства связи все, что позволяет связываться. Эта операция выступает как второй принцип ООП:

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

Рис.1. Весь мир - это объекты, которые передают друг другу сообщения.

О почте Вы знаете больше, чем то, что нужно, чтобы сделать запрос. Вы знаете, что у Вас попросят деньги, что Вам выдадут квитанцию. Все это справедливо и для магазинов, ресторанов. Поскольку категория Post более узкая, чем Service, то любое знание, которым Вы обладаете для категории Service, будет справедливо и для Post.[26,27]

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

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

Утконос представляет проблему для структуры, изображенной на рис. 2. Утконос млекопитающее, но откладывает яйца, следовательно, важно переопределить способ его рождения. Таким образом, необходимо разрешать переопределять информацию, наследуемую из родительских классов. Для поиска метода, подходящего для обработки сообщения, используется следующее правило. [27,51]

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

Рис. 2. Иерархическое дерево.

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

1. Все является объектом.

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

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

4. Каждый объект является представителем класса, который выражает общие свойства объектов.

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

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

Вычисление и моделирование.

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

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

При ООП мы считаем, что вычисление есть моделирование.

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

Сложность

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

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

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

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

Рассмотрим пример организации стека.

Листинг 1.1.

Void init(){datatop=0;}

int top()

{ if(datatop > 0)

return datastack[datatop-1];

return 0;}

int datastack[100];

int datatop=0;void push(int val)

{ if (datatop < 100)

datastack[datatop++]=val; }

int pop()

{ if(datatop > 0)

return datastack[--datatop];

return 0; }

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

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

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

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

Модули решают некоторые, но не все проблемы разработки программного обеспечения, если например, захочется иметь два экземпляра стека. Механизм модуля, позволяя маскировать данные, не дает возможность размножать экземпляры.[26,27,30,51]

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

1. Экспортировать определение типа данных;

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

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

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

Объекты - это почти абстрактный тип данных, но дополненный некоторыми новшествами.

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

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

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

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

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

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

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

Объект проявляет свое поведение путем вызова метода в ответ на сообщение. Интерпретация сообщения зависит от объекта и может быть различной для разных классов объектов.

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

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

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

Объектно-ориентированная парадигма предлагает новый подход к разработке программного обеспечения. Фундаментальная концепция объектно-ориентированной парадигмы состоит в передаче сообщений объектам. [26,27,50,52]

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

1. Инкапсуляция с сокрытием данных - способность отличать внутреннее состояние объекта и поведение от его внешнего состояния и поведения;

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

3. Наследование - способность создавать новые типы, повторно используя, описание существующих типов;

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

Принципы объектно-ориентированного подхода

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

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

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

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

В ООП используется два вида иерархии: иерархия «целое/часть» и иерархия «общее/частное».

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

...

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

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.