Файл: История и развитие методологии объектно-ориентированного программирования. Сферы применения.pdf
Добавлен: 14.05.2023
Просмотров: 407
Скачиваний: 2
СОДЕРЖАНИЕ
Часть I Объектно-ориентированное программирование
Глава 1 Эволюция методологий программирования
1.1 Поколения языков программирования
1.1.1 Начало начал, или первое поколение языков программирования
1.1.2 Развитие алгоритмических абстракций. Второе поколение языков программирования.
1.2. ЗАРОЖДЕНИЕ ОБЪЕКТНОЙ МОДЕЛИ
1.2.1 Объектные языки программирования
1.2.2 Объектно-ориентированные языки
1.2.3 Объектно-ориентированный анализ, дизайн и проектирование
1.3 Парадигмы программирования
Глава 2 Составные части объектного подхода
3.1 Что такое объект с точки зрения ООП
3.3.1 Классификация методов объектов
3.3.3 Связь объектов и автоматов, активные и пассивные объекты
Введение
Первая часть курсовой работы посвящена теоретическим основам объектно-ориентированного программирования (ООП). В концепции теоретических основ ООП взята методология разработанная Г. Бучем и изложенная в его книге, посвященной объектно-ориентированному анализу и проектированию [1, §1–§3]. Книга Буча содержит наиболее полное и систематическое изложение вопросов, связанных с применением объектно- ориентированного подхода в разработке программного обеспечения, доступное на русском языке. Многие основные определения взяты из нее, что отмечается в тексте. Курсовая работа построена по следующей схеме: вначале рассматриваются теоретические основы объектной модели, включая эволюцию, основные принципы и рассмотрение природы классов и объектов; далее следует изучение основных инструментальных средств ООП языка программирования С++; вторая часть посвящена изучению инструментальных средств ООП языка программирования Java.
Часть I Объектно-ориентированное программирование
Глава 1 Эволюция методологий программирования
Давайте обратимся к истории развития языков и методов программирования и разработки информационных систем. Многие наверняка уже не раз сталкивались с такими терминами, как процедурное программирование, или процедурный язык про- граммирования, а также с терминами объектный язык программирования, объектно-ориентированный язык программирования, но многие тонкости в различии этих терминов и технологий очень часто ускользают из поля зрения. Одновременное использование разных методологий при разработке информационной системы часто ведет к серьезным трудностям при ее сопровождении и делает дальнейшее развитие практически невозможным. При выборе методологии в каждом конкретном случае нужно учитывать множество факторов, так как каждая из них имеет свои особенности и границы применимости. То, что сейчас наиболее распространены именно объектно-ориен- тированное программирование и объектно-ориентированный дизайн, еще не значит, что другие методологии потеряли право на существование, а правила, заложенные в них потеряли свою актуальность. Мир программных систем сложен и многообразен, и в разных случаях бывает удобно использовать разные подходы и методы решения возникающих задач. Данная глава призвана упорядочить уже имеющиеся сведения и проследить путь, приведший к возникновению такого мощного и удобного средства разработки программных систем, как объектный подход. Проанализировав путь развития основных языков программирования, можно выделить следующие постоянно присутствующие, сменяющие друг друга тенденции:
• Смещение акцентов от частного (программирование деталей), к общему (программирование более крупных компонент)
• Развитие и совершенствование инструментария программиста (языков программирования высокого уровня и рабочей среды)
• Возрастание сложности программных и информационных систем.
Именно расширение области применения информационных технологий и вычислительной техники служило и продолжает служить движущей силой эволюции методов и инструментов построения программных систем. На протяжении всей истории развития информационных технологий проводилось огромное множество прикладных исследований по методологии проектирования, декомпозиции, абстрагированию и иерархиям. Следствием этих исследований стало появление все более и более выразительных языков программирования. Возникла тенденция перехода от языков, указывающих компьютеру, что делать (императивные языки), к языкам, описывающим ключевые абстракции предметной области (декларативные языки)[1, §2].
1.1 Поколения языков программирования
Из огромного числа языков программирования, появившихся за период развития информационных технологий, лишь наиболее удобные и совершенные были приняты обществом разработчиков и отстояли свое право на существование. Анализируя языки программирования и обстоятельства, сопутствующие их появлению, можно обнаружить множество общих черт. Это позволяет сгруппировать языки по основным используемым принципам и выделить поколения в их развитии. Буч [1, §2] приводит следующую классификацию Вегнера:
• Первое поколение (1954 – 1958)
FORTRAN I Математические формулы
ALGOL-58 Математические формулы
Flowmatic Математические формулы
IPL V Математические формулы
• Второе поколение (1959 – 1961)
FORTRAN II Подпрограммы, раздельная компиляция
ALGOL-60 Блочные структуры, типы данных
COBOL Описание данных, работа с файлами
Lisp Обработка списков, указатели, сборка мусора
• Третье поколение (1962 – 1970)
PL/1 FORTRAN+ALGOL+COBOL
ALGOL-68 Более строгий преемник ALGOL-60
Pascal Более простой преемник ALGOL-60
Simula Классы, абстрактные данные
Как можно видеть, многие идеи, лежащие в основе современных языков программирования, появились в том или ином виде уже к 1970 году. Все последующие языки, за редким исключением, являются потомками или результатом обобщения и развития выше перечисленных. Этому во многом способствовало как широкое распространение мини и микро ЭВМ и связанный с ним рост числа разработчиков программного обеспечения, так и многообразие операционных систем и различных сфер применения информационных технологий.
1.1.1 Начало начал, или первое поколение языков программирования
Начнем свое рассмотрение языков программирования со времен появления первых Цифровых ЭВМ. Еще очень несовершенные и громоздкие, электронные вычислительные машины использовались тогда исключительно для математических и статистических расчетов. Их область применения была ограничена следующими особенностями:
• Малым объем оперативной памяти.
• Несовершенством системы ввода-вывода.
Ввиду данных ограничений, а также малого количества и дороговизны этих машин, на них работали исключительно высококвалифицированные специалисты, способные управлять ими непосредственно на уровне двоичных кодов. Для облегчения процесса программирования вскоре были созданы языки первого поколения. Это были первые языки, которые приближали программирование к предметной области и отдаляли его от конкретной машины. Их словарь практически полностью был математическим. Программы, реализованные на языках первого и начала второго поколения, имели относительно простую структуру, состоящую из подпрограмм и данных, лежащих в глобальной области видимости. Механизмы языков не поддерживали разделения разнотипных данных, что сильно осложняло написание больших программ. Основная сложность при этом заключалась в том, что ошибка или любые изменения в подпрограмме могли иметь губительные последствия для программной системы в целом.
1.1.2 Развитие алгоритмических абстракций. Второе поколение языков программирования.
На момент своего появления, подпрограммы расценивались лишь как средство облегчающее процесс написания программ. Будучи минимальными единицами пере использования, они стали «кирпичиками» для построения первых библиотек. Постепенно они стали играть фундаментальную роль в декомпозиции программных систем. Выделение подпрограмм, как механизм абстрагирования, имело следующие важные последствия:
• Были разработаны различные механизмы передачи параметров.
• Были заложены основания для структурного программирования, что выражалось в появлении языковой поддержки механизмов вложенности подпрограмм и научной разработке структур управления и областей видимости.
• Возникли методы структурного проектирования, основой которых служило использование процедур или подпрограмм в качестве отдельных строительных блоков.
1.1.3 Модульность, как единица построения программных систем, или третье поколение языков программирования
Разрастание программных проектов требовало увеличения коллективов разработчиков и появления механизмов, позволяющих этим коллективам независимо работать над разными частями проекта. Так появились модули. Модуль — отдельно компилируемая части программы, состоящая из наборов данных и подпрограмм. В модули, как правило, собирались подпрограммы, которые, как предполагалось, должны разрабатываться и изменяться совместно. Туда же собирались и данные, которые использовались этими подпрограммами. Постепенно модули стали новым, более крупным механизмом абстракции программных систем. Первоначально языки программирования не имели достаточно развитых механизмов защиты данных одного модуля от использования их процедурами другого. Во многом эта задача ложилась на коллективы разработчиков. Появившиеся различные подходы в разработке программных систем благоприятствовали возникновению огромного количества языков, имеющих те или иные сильные и слабые стороны в реализации этих принципов. Одним из наиболее развитых представителей языков третьего поколения стал язык ALGOL-68. Будучи универсальным и реализуя почти все разработанные к тому времени механизмы в алгоритмических языках, он был достаточно труден для первоначального освоении, однако позволял разрабатывать системы корпоративного масштаба для больших ЭВМ. Благодаря распространению малых ЭВМ, огромную популярность приобрели более простые потомки ALGOL-60 — язык Pascal, до сих пор наиболее широко используемый в академический и учебной среде, и появившийся во второй половине 70-х годов язык C, который при- обрел наибольшую популярность среди профессиональных программистов. Pascal изначально служил средством обучения структурному программированию, а язык C был разработан для написания операционной системы Unix. Классическим потомком языка Pascal, предназначенным для профессионального написания сложных программных комплексов, стал язык Ada, имеющий встроенную поддержку модульности и абстрактных типов данных. Язык C, имеющий гибкий лаконичный синтаксис и простую алгоритмическую структуру (в нем отсутствуют вложенные процедуры), стал очень популярным языком как системного, так и прикладного программирования. Наличие возможности низкоуровневого управления памятью (преобразование типов, наличие указателей на данные и функции), препроцессор и поддержка макросов делают его языком системного программирования, предоставляя средства, ранее доступные для малых ЭВМ только на уровне языка ассемблера. Простота в освоении и чрезвычайная гибкость делают его многофункциональным средством прикладного программирования.
1.2. ЗАРОЖДЕНИЕ ОБЪЕКТНОЙ МОДЕЛИ
Процедурно-ориентированные языки мало подходят для написания программных систем, где центральным место занимают данные, а не алгоритмы. С определенного момента возникла острая необходимость в языковой поддержке описания произвольных объектов окружающего мира. Вводятся абстрактные типы данных. Как хорошо сказал Шанкар: «Абстрагирование, достигаемое посредством использования процедур, хорошо подходит для описания абстрактных действий, но не годится для описания абстрактных объектов. Это серьезный недостаток, так как во многих практических ситуациях сложность объектов, с которыми нужно работать, составляет основную часть сложности всей задачи». Первым языком, в котором нашли свое выражение идеи построения программ на основе данных и объектов стал язык Simula 67. Концепции, заложенные в языке Simula получили свое развитие в серии языков Smalltalk-72,-74,-76,-80, а также в языках C++ и Objective C. При внесении объектно-ориентированного подхода в язык Pascal появился язык Object Pascal. В 90-х годах компания Sun представила миру язык Java, как воплощение идеи платформенной независимости и наиболее полную реализацию концепций объектно-ориентированного программирования, положенных в основу языков Simula 67, Smalltalk, C++.
1.2.1 Объектные языки программирования
Основные принципы и концепции объектной модели в программировании развивались в процессе эволюции множества разных объектных и объектно-ориентированных языков, что привело к некоторой путанице в терминологии. Можно очень хорошо продемонстрировать трансформацию и развитие модульной структуры в объектную на основе классического примера из книги Страуструпа [?, §2]. Представим себе, что нам нужно реализовать такой известный программный механизм как стек. Совершенно естественно, что при этом мы преследуем несколько целей. Во-первых, обеспечить некоторую универсальность (чтобы использовать данный механизм во многих приложениях). И во-вторых, обеспечить защиту внутренних деталей реализации от потенциального воздействия других компонент программ. Рассмотрим решение этой задачи средствами процедурного языка C, далее решим задачу с использованием средств поддержки модульности языка C++, и, наконец, предложим объектную реализацию стека на C++. Для простоты наш стек будет хранить нетипизированные указатели на void*. Это, безусловно не лучшее решение, но в нашем случае цель состоит в демонстрации разных подходов, а не написании профессионального кода для практического использования. Для того, чтобы не загромождать пример лишними подробностями, мы опустим обработку ошибок выделения памяти. В случае использования механизмов языка C, стратегия может быть следующей — мы объявляем набор операций для работы со стеком и заводим некоторую структуру для хранения его содержимого. Ниже приведен пример заголовочного файла для стека, а также файл модуля, где реализованы функции работы со стеком, объявленные в заголовке.