Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

История и развитие методологии объектно-ориентированного программирования. Сферы применения. (Исторические аспекты появления и развития программирования)

Содержание:

Введение

Программирование в привычном его понимании появилось в первой половине XX века. Первые его идеи высказал ещё Чарльз Бэббидж (1792-1871), которого по праву считают отцом компьютера. Он не знал о транзисторах, микросхемах и мониторах, но достаточно точно описал основные принципы, на которых будут строится все вычислительные машины. Развила идею графиня Ада Лавлейс (1815-1852). Её место в истории до сих пор вызывает немало споров, но одно абсолютно точно – именно Ада фактически стала первым известным программистом. Благодаря её трудам стало понятно, что путь к эффективному использованию машин – алгоритмы, описанные в коде.[3]

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

• машинные;

• машинно-ориентированные (ассемблеры);

• машинно-независимые (языки высокого уровня). [1]

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

При разработке современного программного обеспечения широко применяется метод объектно-ориентированного программирования, основанный на применении непроцедурных языков

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

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

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

Задачи исследования:

  1. Выделить основные этапы развития программирования;
  2. Рассмотреть историю развития объектно-ориентированного программирования;
  3. Раскрыть суть методологии объектно-ориентированного программирования;
  4. Рассмотреть основные принципы объектно-ориентированного программирования;
  5. Провести анализ применения различных языков объектно-ориентированного программирования;
  6. Выделить плюсы и минусы объектно-ориентированного программирования

Глава 1. История развития программирования

1.1 Исторические аспекты появления и развития программирования

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

При формулировании понятия «программирование» следует выделить понятие компьютер – это некая машина, способная выполнять различные действия в соответствии с заложенной в нее программой. Именно программа определяет возможность полезного применения ЭВМ, без нее она остается практически ненужной грудой «железа» — проводов, микросхем, пластмассы. Благодаря возможности менять исполняемые программы, закладываемые в память машины без изменения ее электронной схемы, мы получаем удивительное и не характерное для ранее созданных человеком машин свойство — универсальность, то есть способность одной и той же машины выполнять разные функции.[4]

Язык программирования служит двум взаимосвязанным целям: предоставляет программисту аппарат для задания действий, которые должны быть выполнены компьютером, и формирует концепции, которыми пользуется программист, продумывая будущий алгоритм.[8]

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

В 1938 году немецкий инженер Конрад Цузе построил Z1 — первую из трех модификаций своей вычислительной машины. Элементной базой служили списанные с телефонной станции реле — фактически, машина была электромеханической. Программа должна была задаваться с помощью ленты с отверстиями — перфоленты. Однако Цузе, как и леди Лавлейс за век до него, увлекла идея создания универсальной машины, способной решать задачи не только вычислительные, но и из других областей. Он назвал свой проект логической машиной. Но к сожалению она, как и аналитическая машина Бэббиджа, так и не была построена.[7]

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

В начале 50-х годов XX века были созданы языки программирования, которые называются ассемблерами. Вместо одних только нулей и единиц программисты теперь могли пользоваться операторами (MOV, ADD, SUB и т. д.), которые были похожи на слова английского языка. Для преобразования текста программы на ассемблере в понятный компьютеру машинный код использовался компилятор, который загружался в оперативную память ЭВМ. Программы на ассемблере были также машинно-зависимыми, т. е. ассемблеры для различных процессоров существенно различались между собой.[6]

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

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

В 1959 г. создан язык COBOL (Common Business Oriented Language – стандартный язык для делового применения). Предназначался для коммерческих приложений, обрабатывающих большие объемы нечисловых данных.[5]

В 1964 г. Разработан язык BASIC. Первоначально работа велась только в режиме интерактивной (диалоговой) интерпретации. В смысле строгости и стройности является антиподом языка Pascal. Несмотря на это, Basic очень популярен, в особенности на ПК. Существует множество его диалектов, несовместимых между собой. Современные диалекты Basic’а весьма развиты и мало чем напоминают своего предка.

В 1970 г.. Норбертом Винером был разработан язык Pascal, названый в честь французского математика Блеза Паскаля. В Паскале полностью реализована концепция структурного программирования не только путем упорядочения связей.[5]

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

Первым языком, в котором нашли свое выражение идеи построения программ на основе данных и объектов стал язык Simula 67. Концепции, заложенные в языке Simula получили свое развитие в серии языков Smalltalk-72,-74,-76,-80, а также в языках C++ и Objective C. При внесении объектно-ориентированного подхода в язык Pascal появился язык Object Pascal.

В 90-х годах компания Sun представила миру язык Java, как воплощение идеи платформенной независимости и наиболее полную реализацию концепций объектно-ориентированного программирования, положенных в основу языков Simula 67, Smalltalk, C++. [4]

Объектно-ориентированное программирование, разработанное в середине 1970-х гг. Б. Керниганом и Д. Риччи и реализованное в объектно-ориентированных версиях языков C и Pascal, представляет собой отображение объектов реального мира, их свойств (атрибутов) и связей между ними при помощи специальных структур данных.[7]

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

Выделяют следующие этапы развития языков программирования высокого уровня: −

Языки первого поколения (1954−1958)

• FORTRAN 1 Математические формулы

• ALGOL-58 Математические формулы − Языки второго поколения (1959−1961)

• FORTRAN II Подпрограммы

• ALGOL-60 Блочная структура, типы данных

• COBOL Описание данных, работа с файлами

• LISP Обработка списков, указатели, сборка мусора − Языки третьего поколения (1962−1970)

• PL/I FORTRAN+ALGOL+COBOL

• Pascal Простой наследник ALGOL-60

• Simula Классы, абстракция данных − Разрыв преемственности (1970−1980)

• C Эффективный высокоуровневый язык

• FORTRAN 77 Блочная структура, типы данных − Бум ООП (1980−1990)

• Smalltalk 80 Чисто объектно-ориентированный язык

• C++ С + Simula

• Ada83 Строгая типизация; сильное влияние Pascal − Появление инфраструктур (1990−…)

• Java Блочная структура, типы данных

• Python Объектно-ориентированный язык сценариев

• Visual C# Конкурент языка Java для среды Microsoft .NET(http://glebradchenko.susu.ru/courses/bachelor/oop/OOP-PrePrint.pdf)

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

• Язык С++ является прямым потомком алгоритмического языка С;

• Язык Object Pascal разработан на основе алгоритмического языка Pascal. После создания интегрированной среды разработки система программирования получила название Delphi;

• Язык Visual Basic создан корпорацией Microsoft на основе языка QBasic.

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

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

На 3-е поколение языков программирования влияние оказало то, что стоимость аппаратного обеспечения резко упала, при этом, производительность экспоненциально росла. Языки поддерживали абстракцию данных и появилась возможность описывать свои собственные типы данных. В 1970-е годы было создано несколько тысяч языков программирования для решения конкретных задач, но практически все из них исчезли. Осталось только несколько известных сейчас языков, которые прошли проверку временем.[7]

1.2 Исторические этапы развития объектно-ориентированного программирования

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

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

С момента появления первых электронно-вычислительных машин

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

Объектно-ориентированное программирование появилось в результате развития процедурного программирования. Основоположниками объектного подхода в программировании считаются норвежцы Оле Джохан Дал и Кристен Нюгорт, авторы языка Simula. [5]

История Simula началась в 1962 году с проекта Simulation Language, предназначенного для программного моделирования метода Монте-Карло. Нюгорт предложил сотрудничество Оле Джохана Дала, коллеге по экспериментальной группе Министерства обороны Норвегии. В 1965 году у авторов зародилась идея объединить данные с процедурами, их обрабатывающими. После успешного обсуждения возможностей Simula I на саммите НАТО в 1966 г. было решено продолжить его совершенствование. В язык вошли новые средства моделирования и имитации мультипроцессной работы. Авторы также придумали термины «класс» и «объект». В то же время возникла и технология наследования. Создатели Simula ввели в язык возможность использования разными классами общих свойств посредством указания названия класса в виде префикса. После публичного анонса новая технология вызвала интерес в Дании, Германии и СССР. У нас в конце 60–х появилась реализация Simula для УРАЛа-16. Алан Кей внимательно изучал идеи, заложенные в Simula и еще два оригинальных языка — LISP, применявшийся для задач искусственного интеллекта, и LOGO, предназначенный для обучения базовым понятиям программирования.[12]

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

Позже в 1972 г. Кей реализовал свои идеи в новом объектном языке SmallTalk, первоначально названном им Biological System и смоделированном на Бейсике, а затем реализованном на ассемблере.

Именно тогда был предложен термин «объектно-ориентированное программирование» (ООП). Заложенные в SmallTalk идеи ООП до сих пор остались непревзойденными в других языках и системах. [11]

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

В 1976 году Кринстен Нюгорн создал новый язык BETA, в котором ввел концепцию шаблонов — более высокого уровня абстракций, нежели объекты.

В 1980 году Бьерн Страуструп, продолживший дело своих коллег из лаборатории Bell, дополнил язык C концепцией классов, основанной на фреймах и объектных механизмах Simula.

В 1982 году в Мехико прошла 8-я Международная конференция по сверхбольшим базам данных (БД) (VLDB), на которой была предложена концепция объектно-ориентированных БД и рассматривались вопросы расширения существовавших языков запросов к БД.

В 1983 году. Страуструп дал своему творению окончательное название С++. [11]

В 1986 году в Портленде прошла первая всемирная конференция по объектно-ориентированным системам программирования. Возможно, именно прозвучавшие на ней доклады оказали главное влияние на Уильяма Аткинсона, инженера Apple, который через год после этого спроектировал систему HyperCard, прообраз современных визуальных сред быстрой разработки. Эффективность новой технологии оказалась столь высокой, что уже в 1989 году одиннадцать компаний: 3Com, American Airlines, Canon, Data General, Hewlett-Packard, Philips Telecommunications, Sun Microsystems и Unisys, основали группу OMG (Object Management Group), призванную формировать индустриальные стандарты на объектное программирование и упрощать интеграцию приложений с помощью универсальных кросс-платформенных технологий.

OMG первым делом приступила к выработке единого стандарта компонентной модели CORBA (Common Object Request Broker Architecture), набора спецификаций, определяющих способы объектно-ориентированного взаимодействия компонентов промежуточного уровня в гетерогенных средах без привязки к конкретным языкам программирования. С самого начала CORBA нацеливалась на поддержку крупных, индустриальных проектов, и этот подход со временем себя полностью оправдал.[11]

В 1992 году вышел стандарт CORBA 1.0, определяющий главные аспекты функционирования CORBA-систем. В него были включены базовое описание объектной модели, наборы программных интерфейсов поддержки CORBA-систем, а также декларативный язык определения интерфейсов Interface Definition Language (IDL), созданный OMG для описания распределенных интерфейсов.

В 1994 году опубликован стандарт CORBA 2.0, который быстро получил массовое признание, так как представлял собой богатый и глубоко проработанный набор документов и охватывал большинство востребованных на рынке задач. В нем были исправлены недостатки прежней версии, в результате чего CORBA 2.0 начал поддерживать транзакции и понимать универсальную кодировку Unicode, а также появился набор средств обеспечения безопасности и взаимодействия COM- и CORBA-объектов.

Гради Буч и Джеймс Румбах из Rational Software объединили две методологии визуального моделирования Booch и OMT и создали на их основе новый язык UML (Unified Modeling Language).[10]

В 1995 году Sun Microsystems выкладывает в свободный доступ элемент технологии Java — среду HotJava, поддерживающую мобильный код, разработку проекта Green, которая к тому времени считалась в Sun практически пропащей, если бы не развитие Сети. Новинку сразу же лицензирует Netscape Communication, а следом за ней к Java проявляют коммерческий интерес десятки компаний, в том числе Microsoft, IBM, Adobe, Borland, Lotus, Oracle. Корпорация Borland выпустила первую версию среды быстрой визуальной разработки Delphi 1, основанную на концепции библиотек стандартных компонентов. [8]

В 1997 году Sun Microsystems разрабатывает концепцию Enterprise JavaBeans — технологию создания корпоративных Java-компонентов, которые можно исполнять на серверах приложений, реализуя логику крупных, хорошо масштабируемых и защищенных систем на платформенно-независимой основе. [12]

В 2000 году Microsoft анонсирует новую объектную платформу .NET и новый язык программирования C#, объединяющий лучшие свойства С++ и Java. Он был предложен Microsoft во многом в противовес Java.

В 2001 году OMG выпускает спецификацию CORBA 3.0. Она дополнена возможностями асинхронного обмена сообщениями, разработки систем реального времени и создания встраиваемых систем. В ней появились подключаемые компоненты, поддержка XML и средства интеграции различных Интернет-технологий. Особый акцент в третьей версии CORBA сделан на эффективном взаимодействии с Java.

В 2002 году Опубликована последняя официальная версия CORBA 3.0.2.[11]

Вывод

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

Глава 2. Парадигма объектно-ориентированного программирования

2.1 Методология и основные понятия объектно-ориентированного программирования

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

• выделении классов объектов;

• установлении свойств и методов обработки;

• создании иерархии классов, наследовании свойств объектов и методов их обработки. [9]

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

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

Несмотря на то что в различных источниках делается акцент на те или иные особенности внедрения и применения ООП, три основных (базовых) понятия ООП остаются неизменными. К ним относятся:

• наследование (Inheritance)

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

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

• инкапсуляция (Encapsulation)

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

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

• полиморфизм (Polymorphism)

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

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

Программа считается объектно-ориентированной при соблюдении следующих концепций:

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

• в процессе выполнения программы может одновременно использоваться несколько объектов, порожденных от одного класса (экземпляров реализации класса);

• классы организованы иерархически (иерархия означает «быть частью»).

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

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

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

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

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

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

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

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

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

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

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

Связь объектов — это важная составляющая ООП. Существует два основных способа связи объектов. В первом случае каждый объект существует отдельно от другого. В случае необходимости взаимодействия отдельных объектов происходит передача сообщений между этими объектами.[6]

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

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

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

2.2 Сферы применения объектно-ориентированного программирования

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

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

Разработав первый объектно-ориентированный язык программирования Simula 67, его авторы опередили своё время, точно угадав перспективы развития программирования. Но их современники не оценили по достоинству эту разработку, в результате чего Simula 67. не выдержал конкуренции с другими языками программирования (прежде всего, с языком Fortran). Прохладному отношению к языку Simula 67 способствовало и то обстоятельство, что он был реализован как интерпретируемый (а не компилируемый) язык, что было совершенно неприемлемым в 60-е годы, так как интерпретация связана со снижением эффективности (скорости выполнения) программ.[11]

Использование объектно-ориентированного программирования является хорошим решением при разработке крупных программных проектов. Чем проект объемнее и сложнее, тем выгоднее становится использование объектно-ориентированной технологии программирования. Одним из наибольших преимуществ объектно-ориентированного программирования является возможность многократного использования программного кода.[5]

Выводы

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

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

Глава 3. Исследование эволюции объектно-ориентированных языков программирования. Достоинства и недостатки объектно-ориентированного программирования

3.1 Эволюция объектно-ориентированных языков программирования

В основу концепции всех существующих языков объектно-ориентированного программирования, легли идей Simula-67. Язык Simula-67 основывался на языке Algol-60. Отличительной чертой Simula-67 было наличие параметра у объекта.

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

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

Языки программировании для выполнения операций одного вида, но с разными типами данных используют разные функции, следовательно за ростом количества типов данных, растёт количество функций для выполнения одного и того же действия. [9]

Кроме того, к недостаткам языка можно отнести отсутствие средств для отладки приложения и необходимость выполнения определенного алгоритма действий для запуска программы. При отладке крупных приложений на выполнение этого алгоритма и поиск причины ошибки, не выявленной компилятором, тратится много времени, т.е. с увеличением сложности разрабатываемого ПО недопустимо увеличивается время на отладку программы . Также такие ошибки приводят к аварийному завершению программы. И чем больше объем кода, тем больше вероятность пропустить подобную ошибку, т.е. с увеличением объема кода недопустимо снижается надежность программы.[4]

Так же, при реализации механизма одиночного наследования в языке возникает противоречие: с увеличением количества родительских классов до недопустимого значения увеличивается объём дублируемых данных .[9]

Перечисленные выше и другие противоречия были разрешены в языках Smalltalk-80, С++, Eiffel.

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

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

Часть противоречий Simula-67 была разрешена в языке Smalltalk-80 следующими способами. Например, при использовании приема «универсальности» в язык была добавлена возможность перегрузки операторов, т.е. возможность одновременного существования в одной области видимости нескольких различных вариантов применения оператора, имеющих одно и то же имя, но различающихся типами параметров, к которым они применяются. С помощью закона перехода в надсистему создана среда разработки программы, обладающая пользовательским интерфейсом и предоставляющая средства для отладки программ.

Таким образом, в языке появилось большое количество новых механизмов реализации ООП.

Несмотря на то, что в языке Smalltalk-80 была разрешена часть противоречий Simula-67, Smalltalk-80 унаследовал ряд противоречий этого языка.[12]

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

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

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

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

При использовании приема «объединение» были введены возможность объединения дублируемых параметров в одном из классов и возможность объекту наследовать несколько классов, т.е. появился механизм множественного наследования.[1]

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

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

В языке Eiffel были разрешены не только часть противоречий C++, но и противоречия предыдущих языков.

Например, при помощи приема «предварительное действие» были разработаны дополнительные операторы, регулирующие порядок наследования и вызова функций.[9]

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

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

  • систематизировать знания о существующих механизмах реализации объектноориентированных возможностей;
  • обосновать эволюцию механизмов ООП;
  • выявить противоречия, которые запускают механизм эволюции;[7]

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

К настоящему времени насчитывается более сотни различных объектных и объектно-ориентированных языков.

Объектно-ориентированное программирование является в настоящее время основой всей индустрии прикладного программирования благодаря выигрышу в конкурентной борьбе с альтернативными технологиями.[12]

3.2 Достоинства и недостатки объектно-ориентированного программирования

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

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

ООП дает возможность создавать расширяемые системы (extensible systems). Это одно из самых значительных достоинств ООП и именно оно отличает данный подход от традиционных методов программирования. Расширяемость (extensibility) означает, что существующую систему можно заставить работать с новыми компонентами, причем без внесения в нее каких-либо изменений. Компоненты могут быть добавлены на этапе выполнения.[3]

Расширение типа (type extension) и вытекающий из него полиморфизм переменных оказываются полезными преимущественно в следующих ситуациях:

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

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

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

Объектно-ориентированное программирование требует знания четырех вещей.

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

Многоразовое использование требует от программиста познакомиться с большими библиотеками классов. А это может оказаться сложнее, чем даже изучение нового языка программирования. Библиотека классов фактически представляет собой виртуальный язык, который может включать в себя сотни типов и тысячи операций. В языке Smalltalk, к примеру, до того, как перейти к практическому программированию, нужно изучить значительную часть его библиотеки классов. А это тоже требует времени.[9]

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

Очень трудно изучать классы, не имея возможности их «пощупать». Только с приобретением некоторого опыта можно уверенно себя почувствовать при работе с использованием объектно-ориентированное программирование.[11]

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

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

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

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

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

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

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

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

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

В гибридных языках типа Oberon-2, Object Pascal и C++ посылка сообщения приводит лишь к вызову через указатель процедурной переменной. На некоторых машинах сообщения выполняются лишь на 10% медленнее, чем обычные процедурные вызовы. И поскольку сообщения встречаются в программе гораздо реже других операций, их воздействие на время выполнения влияния практически не оказывает.[2]

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

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

Излишняя универсальность. Неэффективность может также означать, что программа имеет ненужные возможности. В библиотечном классе часто содержится больше методов, чем это реально необходимо. А поскольку лишние методы не могут быть удалены, то они становятся мертвым грузом. Это не воздействует на время выполнения, но влияет на возрастание размера кода.[10]

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

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

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

Oberon избрал третий путь избавления от излишней универсальности.

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

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

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

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

Выводы.

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

Заключение

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

Библиографический список

1.Ашарина, И.В. Объектно-ориентированное программирование в C++: лекции и упражнения: учебное пособие для студ. вузов / И. В. Ашарина. – М.: Горячая линия-Телеком, 2008. – 320 с.: ил.

2. Буч, Г. Объектно-ориентированный анализ и проектирование с примерами приложений, 3-е изд. / Г. Буч и др. // Пер. с англ. – М.: «И.Д. Вильямс», 2010. – 720 с.

3. Подбельский, В.В. Язык Си++ : Учеб. пособие для вузов по направлениям «Приклад. математика» и «Вычисл. машины, комплексы, системы и сети» / В.В. Подбельский // М.: Финансы и статистика , 2001 г. – 559 с.

4. Павловская, Т.В. C/C++. Программирование на языке высокого уровня: учебник для студентов вузов / Т. А. Павловская. – СПб.: Лидер, 2010. – 461 с.: ил.

5. Иванова, Г.С. Объектно-ориентированное программирование: учебник для студ. вузов / Г.С. Иванова, Т.Н. Ничушкина, Е.К. Пугачев; под ред. Г.С. Ивановой. – 3-е изд.,стереотип. – М.: Изд-во МГТУ им. Н.Э. Баумана, 2007. – 368 с.: ил.

6. Дорогов В. Г. Основы программирования на языке С: Учебное пособие / В.Г. Дорогов, Е.Г. Дорогова; Под общ. ред. проф. Л.Г. Гагариной – М.: ИД ФОРУМ: ИНФРА-М, 2011. – 224 с.

7. Кузин А.В. Программирование на языке Си/А.В.Кузин, Е.В.Чумакова – М.: Форум, НИЦ ИНФРА-М, 2015. – 144 с. http://znanium.com/bookread2.php?book=505194

8. Парфенов Д.В. Язык Си: кратко и ясно: Учебное пособие / Д.В. Парфенов. – М.: Альфа-М: НИЦ ИНФРА-М, 2014. – 320 с.

9. Научная электронная библиотека eLIBRARY.RU: http:/www.eLIBRARY.RU (дата обращения 5. 09.18)

10. Ресурс Цифровые учебные материалы http://abc.vvsu.ru/ (дата обращения 5.09.18)

11. ЭБС «Руконт»: http://www.rucont.ru/ (дата обращения 7.09.18)

12. ЭБС «Юрайт»: http://www.biblio-online.ru/ (дата обращения 4.09.18)