Объектно-ориентированный подход к разработке ПО
Сдам Сам

ПОЛЕЗНОЕ


КАТЕГОРИИ







Объектно-ориентированный подход к разработке ПО





Под объектно-ориентированным программированием (object-oriented programming, OOP) следует понимать методологию реализации, при которой программа организуется, как совокупность сотрудничающих объектов, каждый из которых является экземпляром какого-либо класса, а классы образуют иерархию наследования. При этом классы обычно статичны, а объекты очень динамичны, что поощряется динамическим связыванием и полиморфизмом (пока не обращайте внимания на то, что большая часть слов этого определения Вам не понятна). Несмотря на то, под OOP следует понимать только то, что было написано выше, под ним часто понимают объектно-ориентированный подход к созданию ПО. Последний наравне с OOP включает в себя объектно-ориентированный анализ (object-oriented analisys, OOA) н объектно-ориентированное проектирование (object-oriented design). Все это понятия тесно связанны с понятиями объекта, класса и объектной модели.

Понятия объекта и класса

Природа объектов

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

Класс - множество объектов с общей структурой и поведением.

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



Теперь более подробно разберемся с определением объекта. А именно с понятиями состояния, поведения и идентичности.

Состояние

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

Поведение

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

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

C одной стороны, поведение объекта изменяет его состояние. С другой – поведение зависит от состояния. Действительно, рассмотрим поведение автомата. С одной стороны, одна из частей его поведения – принять монету. Эта часть поведения влияет на часть состояния–количество монет. С другой – именно часть состояния - количество монет определяет в некоторой степени поведение автомата. А именно, наливать ли кофе в стакан или нет. Таким образом можно прийти к выводу, что состояние объекта представляет суммарный результат его поведения.

Поведение объекта строится из его операций. Существует три вида операций

· Модификатор - операция, которая изменяет состояние объекта

· Селектор - операция, считывающая состояние объекта, но не меняющая состояния

· Итератор - операция, позволяющая организовать доступ ко всем частям объекта в строго определенной последовательности

Идентичность

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

Отношения между объектами

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

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

Отношение типа “связь”

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

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

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

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

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

Отношение типа “агрегация”

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

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

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

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

Большинство объектных нотаций вводит понятие диаграммы объектов. Диаграмма объектов - часть системы обозначений объектно-ориентированного проектирования; используется, чтобы наглядно показать объекты и отношения между ними в логическом проекте системы. Может отражать всю объектную структуру или часть ее; обычно иллюстрирует смысл механизмов в логическом проекте. Отдельная диаграмма объектов - моментальный снимок из жизни системы. Часто диаграмму объектов называют диаграммой сотрудничества (collaboration diagram). Основные обозначения на этой диаграмме следующие:

 

Рисунок 1.1 Обозначение объекта

 

Рисунок 1.2 Отношение типа "связь"

Помимо диаграмм сотрудничества, существует еще один вид диаграмм объектов – диаграммы последовательностей (sequence diagram). Диаграммы последовательностей служат тем же целям, что и диаграммы сотрудничества.

Отношение типа “агрегация” между объектами не имеет специального обозначение. Дело в том, что отношению «агрегация» между объектами, соответствует отношение «агрегация» между их классами. Для агрегации между классами существует специальное обозначение, но о нем поговорим чуть позже.

Природа классов

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

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

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

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

Отношения между классами

Всего между классами существует 6 видов отношений: ассоциация, наследование, агрегация, использование, инстанцирование и метакласс.

 

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

 

Рисунок 1.3 Обозначение класса

Теперь рассмотрим каждое отношение более подробно.

Ассоциация

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

Рисунок 1.4 Обозначение ассоциации

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

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

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

Наследование

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

На диаграммах классов наследование обозначается следующим образом:

Рисунок 1.5 Обозначение наследования

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

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

У класса обычно бывает два вида клиентов:

  • экземпляры;
  • подклассы.

Часто полезно иметь для них разные интерфейсы. В частности, мы хотим показать только внешне видимое поведение для клиентов-экземпляров, но нам нужно открыть служебные функции и представления клиентам-подклассам. Этим объясняется наличие открытой, защищенной и закрытой частей описания класса в языке C++: разработчик может четко разделить, какие элементы класса доступны.

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

Множественное наследование

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

Множественное наследование прямо поддерживается в языках C++ и CLOS, а также, до некоторой степени, в Smalltalk. Необходимость множественного наследования в OOP остается предметом горячих споров. По нашему опыту, множественное наследование - как парашют: как правило, он не нужен, но, когда вдруг он понадобится, будет жаль, если его не окажется под рукой.

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

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

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

Агрегация

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

 

Рисунок 1.6 Логическая агрегация

 

Рисунок 1.7. Физическая агрегация (композиция)

Инстанцирование

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

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

Метакласс

Как было сказано, любой объект является экземпляром какого-либо класса. Что будет, если мы попробуем и с самими классами обращаться как с объектами? Для этого нам надо ответить на вопрос, что же такое класс класса? Ответ - это метакласс. Иными словами, метакласс - это класс, экземпляры которого суть классы. Метаклассы венчают объектную модель в чисто объектно-ориентированных языках. Соответственно, они есть в Smalltalk и CLOS, но не в C++.

 

Объектная модель

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

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

Абстрагирование

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

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

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









Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:


©2015- 2018 zdamsam.ru Размещенные материалы защищены законодательством РФ.