Стратегии взаимодействия объектов в программе. Программа как система взаимодействующих объектов. Система объектов, управляемых сообщениями
Программа, как система взаимодействия объектов.
Сущность ООП заключается в первичности данных и их обработки. Причем, любая сущность в программе должна являться объектом. Логическим завершением этого подхода является взгляд на программу как на систему взаимодействующих объектов. При таком подходе, однако, теряется само представление о программе, как о едином потоке данных. При этом важным становится вопрос: Сколько объектов в программе, как они получают информацию друг о друге, кто и когда их создал и уничтожает?
Следует провести грань между динамическими и обыкновенными объектами и переменными. Обычные объекты, имеющие имя, привязаны к управляющей структуре программы, и поэтому, так или иначе связаны с потоком управления программы.
В отличие от статических, динамические объекты могут создаваться когда угодно, и их создание и уничтожение не связано с управляющей структурой программы. Именно динамические объекты позволяют более полно реализовать стратегию программы в виде взаимодействующих между собой объектов.
Как объекты будут знать о существовании друг друга?
Как реализовать универсальные средства, которые будут поддерживать связь и взаимодействие объектов?
1) Программе необходима интегрированная структура данных, которая объединяет все ее объекты, независимо от их класса, времени и места создания.
2) В проге необходимы универсальные средства взаимодействия объектов.
Достаточно иметь базовый класс, который обладает всеми свойствами, когда конструктор включает его в статическую структуру данных.
49. Элементы объектно-ориентированного анализа и объектно-ориентированного проектирования. Диаграммы классов. Отношения классов: ассоциация, наследование, агрегация, использование.
Основными элементами ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОЕКТИРОВАНИЯ являются:
абстрагирование;
инкапсуляция;
модульность;
иерархия.
Кроме основных, имеются еще три дополнительных элемента, не являющихся в отличие от основных строго обязательными:
типизация;
параллелизм;
устойчивость.
Диаграмма классов показывает классы и их отношения, тем самым представляя логический аспект проекта. Отдельная диаграмма классов представляет определенный ракурс структуры классов. На стадии анализа мы используем диаграммы классов, чтобы выделить общие роли и обязанности сущностей, обеспечивающих требуемое поведение системы. На стадии проектирования мы пользуемся диаграммой классов, чтобы передать структуру классов, формирующих архитектуру системы.
Типы отношений
Известны три основных типа отношений между классами
Во-первых, это отношение "обобщение/специализация" (общее и частное), известное как "is-a”.Во вторых, это отношение "целое/ часть", известное как "part of".
В-третьих, это семантические, смысловые отношения, ассоциации.
Языки программирования выработали несколько общих подходов к выражению отношений этих трех типов. В частности, большинство объектно-ориентированных языков непосредственно поддерживают разные комбинации следующих видов отношений: ассоциация наследование агрегация использование инстанцирование метакласс.
Альтернативой наследованию является делегирование, при этом объекты рассматриваются как прототипы, которые делегируют свое поведение родственным им объектам. Таким образом, классы становятся не нужными.
Из шести перечисленных видов отношений наиболее общим и неопределенным является ассоциация. Обычно аналитик констатирует наличие ассоциации и, постепенно уточняя проект, превращает ее в какую-то более специализированную связь.
Наследование, вероятно, следует считать самым интересным семантически. Оно выражает отношение общего и частного. Полезна также агрегация, отражающая отношения целого и части между экземплярами классов. Нелишне добавить отношение использования, означающее наличие связи между экземплярами классов. Метакласс - это класс классов, что позволяет нам трактовать классы как объекты.
Ассоциация
Ассоциация - смысловая связь. По умолчанию, она не имеет направления (если не оговорено противное, ассоциация, как в данном примере, подразумевает двухстороннюю связь) и не объясняет, как классы общаются друг с другом (мы можем только отметить семантическую зависимость, указав, какие роли классы играют друг для друга). Однако именно это нам требуется на ранней стадии анализа. Итак, мы фиксируем участников, их роли и (как будет сказано далее) мощность отношения.
Мощность. На практике важно различать три случая мощности ассоциации:
"один-к-одному"
"один-ко-многим"
"многие-ко-многим".
Наследование
Одиночное наследование. Попросту говоря, наследование - это такое отношение между классами, когда один класс повторяет структуру и поведение другого класса (одиночное наследование) или других (множественное наследование) классов. Класс, структура и поведение которого наследуются, называется суперклассом. Производный от суперкласса класс называется подклассом. Это означает, что наследование устанавливает между классами иерархию общего и частного. В подклассе структура и поведение исходного суперкласса дополняются и переопределяются. Наличие механизма наследования отличает объектно-ориентированные языки от объектных.
Подкласс обычно расширяет или ограничивает существующую структуру и поведение своего суперкласса.
Самый общий класс в иерархии классов называется базовым. В большинстве приложений базовых классов бывает несколько, и они отражают наиболее общие абстракции предметной области. На самом деле, особенно в C++, хорошо сделанная структура классов - это скорее лес из деревьев наследования, чем одна многоэтажная структура наследования с одним корнем. Но в некоторых языках программирования определен базовый класс самого верхнего уровня, который является единым суперклассом для всех остальных классов. У класса обычно бывает два вида клиентов:
экземпляры;
подклассы.
Часто полезно иметь для них разные интерфейсы. В частности, мы хотим показать только внешне видимое поведение для клиентов-экземпляров, но нам нужно открыть служебные функции и представления клиентам-подклассам. Этим объясняется наличие открытой, защищенной и закрытой частей описания класса в языке C++: разработчик может четко разделить, какие элементы класса доступны для экземпляров, а какие для подклассов.
Есть серьезные противоречия между потребностями наследования и инкапсуляции. В значительной мере наследование открывает наследующему классу некоторые секреты. На практике, чтобы понять, как работает какой-то класс, часто надо изучить все его суперклассы в их внутренних деталях. Наследование подразумевает, что подклассы повторяют структуры их суперклассов.
Поведение суперклассов также наследуется. В большинстве языков допускается не только наследование методов суперкласса, но также добавление новых и переопределение существующих методов.
В C++ функция, объявленная виртуальной, может быть в подклассе переопределена, а остальные - нет.
Наследование и типизация.
В большинстве объектно-ориентированных языков программирования при реализации метода подкласса разрешается вызывать напрямую метод какого-либо суперкласса. Как видно из примера, это допускается и в том случае, если метод подкласса имеет такое же имя и фактически переопределяет метод суперкласса. В C++ метод любого достижимого вышестоящего класса можно вызывать, добавляя имя класса в качестве префикса, формируя квалифицированное имя метода. Вызывающий объект может ссылаться на себя с помощью предопределенного указателя this.
На практике метод суперкласса вызывается до или после дополнительных действий. Метод подкласса уточняет или дополняет поведение суперкласса.
Отношение агрегации ("включать как часть") имеет место, когда второе понятие является составной частью первого, но оба эти понятия не совпадают ни в каком смысле независимо от уровня общности абстракции. Например, автомобиль Car имеет двигатель Engine, хотя ясно, что это не тот случай, когда Car является экземпляром Engine или Engine является экземпляром Car. Класс СCar тем не менее является экземпляром класса автомобилей СVehicle, который в свою очередь являетсяэкземпляром класса транспортных средств СMeansOfTransportation. Аналогично проверке для наследования, чтобы проверить отношение агрегации, можно составить предложение "X включает Y как часть" и оценить его корректность. В большинстве случаев различие между агрегацией и наследованием очевидно. Но иногда оно может быть сомнительно или зависеть от обстоятельств. Отношение использования означает наличие связи между объектами классов. Вязыке Си++ (и в некоторых других) наряду с наследованием есть специфическая раз-новидность обобщения, которая называется параметризацией.50. Элементы объектно-ориентированного анализа и объектно-ориентированного проектирования. Диаграмма объектов: назначение, отношение между объектами
Основными элементами ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОЕКТИРОВАНИЯ являются:
абстрагирование;
инкапсуляция;
модульность;
иерархия.
Кроме основных, имеются еще три дополнительных элемента, не являющихся в отличие от основных строго обязательными:
типизация;
параллелизм;
устойчивость.
Диаграммы состояний (statechart diagrams) показывают возможные состояния отдельных компонентов или системы в целом, переходы между ними в ответ на какие-либо события и выполняемые при этом действия.
Состояния показываются в виде прямоугольников с закругленными углами, переходы — в виде стрелок. Начальное состояние представляется как небольшой темный кружок, конечное — как пустой кружок с концентрически вложенным темным кружком. Состояния могут быть устроены иерархически: они могут включать в себя другие состояния, даже целые отдельные диаграммы вложенных состояний и переходов между ними. Пребывая в таком состоянии, система находится ровно в одном из его подсостояний. Переходы могут происходить между состояниями одного уровня, но могут также вести из некоторого состояния в подсостояние соседнего или, наоборот, из подсостояния в некоторое состояние, находящее на том же уровне, что и объемлющее состояние.
На переходе между состояниями указываются следующие данные:
- Событие, приводящее к выполнению этого перехода. Обычно событие — это вызов некоторой операции в одном из объектов или приход некоторого сообщения, хотя могут указываться и абстрактные события.
- Условие выполнения (охранное условие, guardian). Это условие, зависящее от параметров события и текущих значений глобальных переменных, выполнение которого необходимо для выполнения перехода. При наступлении нужного события переход выполняется, только если его условие тоже выполнено.
Условие перехода показывается в его метке в квадратных скобках.
- Действие, выполняемое в дополнение к переходу между состояниями. Обычно это вызовы каких-то операций и изменения значения глобальных переменных.
Действие показывается в метке перехода после слеша (символа ‘/’). При этом изменения значений переменных перечисляются в начале, затем, после знака ‘^’, указывается вызов операции.
Диаграммы состояний используются часто, хотя требуется довольно много усилий, чтобы разработать их с достаточной степенью детальности.
51. Элементы объектно-ориентированного анализа и объектно-ориентированного проектирования. Диаграмма объектов: назначение, отношение между объектами
Диаграммы объектов (object diagrams)
Этот тип диаграмм предназначен для описания какого-либо фрагмента системы с помощью объектов (objects) - экземпляров классов. Объект является конкретным runtime-экземпляром некоторого класса, имеющим средство уникальной идентификации, позволяющее отличить его от других объектов того же класса, а также конкретные значения атрибутов и связей. Понятно, что все возможные экземпляры всех классов на диаграммах не изобразить - их слишком много. Поэтому на диаграммы объектов попадают только те экземпляры, которые реально существуют в некотором фрагменте системе в некоторый момент ее работы.
На этом рисунке изображена следующая конфигурация сервера службы телефонных заявок: один диспетчер (объект ':CDispatcher'), один объект, работающий с PBX (':PBX_Agent') и два оператора – объекты 'Tester1:COperator' и 'Tester2:CSubOperator'.
Понятно, что информация об экземплярах классов необходима вовсе не для спецификации системы (для этого используются, например, диаграммы классов), а для обсуждения некоторого ее фрагмента. Объект является частным случаем общей концепции экземпляров в UML. Не только классы, но и другие сущности (например, узлы диаграмм развертывания) могут иметь экземпляры.
Общее правило для отображения имен экземпляров таково:
<идентификатор1>: <идентификатор2>,где <Идентификатор1> - это имя экземпляра, а <Идентификатор2> - имя его классификатора. Строка с именем должна быть подчеркнута.У объекта может быть также секция атрибутов, где принято указывать значения для атрибутов его класса.Объект может не иметь имени, как верхние два объекта. Объект также может не иметь класса (или пока не иметь). Наконец, объект может вообще не иметь никакого имени, как и любая конструкция UML. Ведь CASE-пакеты поддерживают идентификацию сущностей UML-моделей по внутренним идентификаторам. Это не очень правильно, но удобно на практике: имена, как и многое другое, можно добавить позже.Нужно отметить, что изображение имен классов у объектов, как правило, можно отключать, но это не означает, что их нет.Объекты соединяются друг с другом связями (links). Так же как объекты - это экземпляры классов, так и связи - это экземпляры соответствующих ассоциаций. Однако же в конкретной модели связи могут не иметь ассоциаций. Ведь можно захотеть "накидать" модель объектов просто так, для какого-то документа, обсуждения и пр. И не обязательно строить большую модель с классами. Однако общее определение объектов и связей от этого не страдает - предполагается, что где-то там, за пределами представленных здесь примеров, объектам и связям соответствуют какие-то классы и ассоциации - просто мы не определяем, какие.