Тема 1.5  Обьектно-ориентированое программирование

 

Прототипом объектно-ориентированного программирования послужил ряд средств, входящих в состав языка SIMULA-67. Но в самостоятельный стиль оно оформилось с появлением языка SMALLTALK, разработанного А. Кеем в 1972 году и первоначально предназначенного для реализации функций машинной графики.

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

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

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

К наиболее современным объектно-ориентированным языкам программирования относятся C++ и Java

Язык C++ был разработан в начале 80-х годов Б. Страуструпом, сотрудником лаборатории Bell корпорации AT&T. Им была создана компактная компилирующая система, в которой за основу был взят язык С, дополненный элементами языков BCPL,Simula-67 и Algol-68. К июлю 1983 года появился язык С с классами, а чуть позднее — C++. К 1990 году была выпущена третья версия языка C++, принятая комитетом ANSI в качестве исходного материала для его стандартизации. 

В 1990 году сотрудник корпорации Sun Д. Гослинг на основе расширения C++ разработал объектно-ориентированный язык Oak, основным достоинством которого было обеспечение сетевого взаимодействия различных по типу устройств. Новая интегрируемая в Internet версия языка, получила название Java. Первый броузер, который поддерживал язык Java, разработан программистом корпорации Sun П. Нафтоном и получил название HotJava. С января 1995 года Java получает распространение в Internet

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

Принципиальной разницей между Java и C++ является то, что первый из них является интерпретируемым, а второй — компилируемым. Синтаксис языков практически полностью совпадает. 

С точки зрения возможностей собственно объектно-ориентированных средств язык Java обладает рядом преимуществ перед языком C++. Так, язык Java демонстрирует более гибкую и мощную систему инкапсуляции информации. Механизм наследования, реализованный в Java, обязывает к более строгому подходу к программированию, что улучшает надежность и понимаемость кода. Язык же C++ обладает сложной, неадекватной и трудной для понимания системой наследования. Возможности динамического связывания объектов одинаково хорошо представлены в обоих языках, однако, синтаксическая избыточность C++ заставляет и здесь отдать предпочтение языку Java

В силу своей конструктивности идеи объектно-ориентированного программирования используются во многих универсальных процедурных языках. Так, например, в состав интегрированной системы программирования на языке PASCAL (корпорации BorlandInternational) версии 5.5 входит специальная библиотека объектно-ориентированного программирования TurboVision

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

 

 

Обзор объектно-ориентированного анализа и проектирования

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

Затем объектно-ориентированное проектирование переходит от моделирования предметной области к моделированию области реализации. Структура нашего класса теперь начинает включать описания специфических компьютерных объектов. Например: классы интерфейса пользователя (окна, меню, и т.д.), классы управления задачами (процессы, семафоры, и т.д.), классы обработки данных (списки, стеки, очереди, и т.д.). Поскольку объектно-ориентированный анализ и проектирование используют тот же самый язык (и могут использовать те же самые системы обозначений), проще (и более выгодно) выполнять оба процесса параллельно и итерационно. Как указывает Гради Буч (Grady Booch):

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

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

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

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

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

Объектно-ориентированное проектирование. Резюме

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

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


Почему объектная ориентация работает

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

·         Объектная ориентация работает на более высоком уровне абстракции.

Объектная ориентация работает на более высоком уровне абстракции

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

Жизненный цикл объектно-ориентированный программы не требует никаких "прыжков"

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

Ошибка! Неизвестный аргумент ключа.

Рис. 2. Каскадный ("прыжковый") подход к разработке программного обеспечения.

Данные стабильнее функций

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

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

В ходе всех этих изменений основа системы остается сравнительно постоянной. Эта основа - данные. Например, отчеты и формы для сбора данных могут изменяться со временем, но тот факт, что программное обеспечение для сбора и подготовки данных должно иметь дело с доходом, расходами, выводами, таблицами и т.д., остается незыблемым. Реляционная система управления базами данных (РСУБД) может использовать более эффективные схемы индексации или новые языки управления для доступа к данным, но тот факт, что РСУБД должна иметь дело с таблицами, индексами, схемами и соотношениями, остается неизменным. Это означает что система, сформированная на основе "структурных совокупностей, реализуемых абстрактными типами данных" (см. выше) будет способна продолжить использовать тех же самых типов данных (классов) в ходе всего жизненного цикла программы. Функциональные реализации классов изменятся, но "Инкапсуляция и сокрытие информации работают вместе, чтобы изолировать одну часть системы от других, позволяя коду быть модифицируемым и расширяемым, а ошибки можно зафиксировать без риска ввести ненужные и непреднамеренные побочные эффекты."

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

Усиление роли хороших методов программирования

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