Моделирование и проектирование программного обеспечения Лекция xx. Проектирование связей между классами.

Презентация:



Advertisements
Похожие презентации
Объекто-ориентированное проектирование Паттерны проектирования. 28 февраля 2008 г. 4 курс Технологии программирования.
Advertisements

Методология объектно- ориентированного программирования.
WORK WITH UML Универсальный язык моделирования (UML) Studybook for students Author Dudnik Oxana.
1 Диаграммы реализации (implementation diagrams).
Что такое паттерны (шаблоны) проектирования? Эффективные способы решения характерных задач проектирования Обобщенное описание решения задачи, которое.
Полиморфизм. Полиморфизм – это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.
Чистый код паттерны проектирования Олег Антонов Senior Web Developer MobiDev Corporation.
Организация программного кода при создании информационных систем Подготовил: Студент группы МЭК-21 Акименко В. И. Руководитель: Доц. Яровенко А. Н.
Проектирование архитектуры ИСО 1. UML 2 Структура определения языка 4.
Что такое связи между таблицами В реляционной базе данных связи позволяют избежать избыточности данных. Например, в ходе создания базы данных, содержащей.
Лекция 8 Обзор паттернов проектирования (Design patterns)
Диаграммы UML Диаграмма классов (Class Diagram). Основные вопросы Что такое диаграмма классов Компоненты диаграммы классов и их назначение Пример диаграммы.
В. И. Дихтяр ИНФОРМАТИКА Российский университет дружбы народов Институт гостиничного бизнеса и туризма Раздел 3Моделирование объектов и процессов и его.
Унифицированный язык моделирования UML является графическим языком для визуализации, конструирования и документирования систем, в которых большая роль.
2. UML – унифицированный язык моделирования систем.
Разработка программного обеспечения при объектном подходе Объектно-ориентированный подход.
Языки и методы программирования Преподаватель – доцент каф. ИТиМПИ Кузнецова Е.М. Лекция 7.
OOП Инна Исаева. Подпрограмма – это большая программа, разделённая на меньшие части. В программе одна из подпрограмм является главной. Её задача состоит.
АЛГОРИТМЫ Умение составлять алгоритмы просто необходимо, если человек хочет поручить обработку информации машине Алгоритм - определенная последовательность.
Трехслойная архитектура приложений, основанных на использовании баз данных.
Транксрипт:

Моделирование и проектирование программного обеспечения Лекция xx. Проектирование связей между классами

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

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

Степень связанности разных отношений классов Все виды связанности можно упорядочить по степени убывания следующим образом: 1.Наследование (наиболее строгая связанность). 2.Композиция 3.Агрегирование 4.Ассоциация

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

Сравнение агрегации и наследования Наследование – очень мощный метод. – Оно является ключевым механизмом формирования полиморфизма в строго типизированных языках программирования, таких как Java, C# и C++. Однако неопытные ОО проектировщики и программисты часто используют его неправильно. Необходимо понимать, что наследование имеет некоторые нежелательные характеристики: – Наследование – самая строгая форма связанности классов. – Это самая строгая из возможных форма связанности двух или более классов.

В иерархии классов будет плохая инкапсуляция. – связано с тем, что изменения базового класса передаются вниз по иерархии и приводят к изменениям всех подклассов. Такое явление называется проблемой «хрупкости базового класса», когда изменения базового класса имеют огромное влияние на другие классы системы.

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

Пример Задача моделирования сотрудников организации: есть сотрудник, которые могут иметь разные должности. – Решение выполненное неопытным разработчиком. Имеется смысловая (семантическая) ошибка. – служащий (Employee) это именно сама должность (Job) или указание на то, что служащий занимает некоторую должность?

При использовании агрегации получаем правильный смысл: – у служащего (Employee) есть должность (Job). При такой более гибкой модели у служащих при необходимости может быть несколько должностей. Подклассы всегда должны представлять «особую разновидность чего-либо», а не «выполняемую роль».

Множественное наследование При множественном наследовании у класса может быть более одного родителя. Иногда возникает потребность наследования от нескольких родителей. Такое наследование называют множественным. Его поддерживают не все ОО языки программирования, например в Java и C# допускается только единичное наследование. – На практике отсутствие поддержки множественного наследования не является проблемой, поскольку его всегда можно заменить единичным наследованием и делегированием. Даже несмотря на то, что иногда множественное наследование предлагает более элегантное решение задачи проектирования, оно может использоваться, только если целевой язык реализации его поддерживает.

Требования к множественному наследованию Родители должны быть семантически не связанными. В случае наличия какого-либо совмещения в семантике базовых классов между ними возможны непредвиденные взаимодействия. – Это может привести к необычному поведению подкласса. У суперклассов не должно быть общих родителей. В противном случае в иерархии наследования образуется цикл и возникает множество путей наследования одних и тех же возможностей от более абстрактных классов.

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

Рекомендация В начале использования ОО подхода наследование часто считали основным механизмом многократного использования. Однако разработчики выявили появление неприемлемых ограничений, накладываемых наследованием. В связи с этим в настоящее время широкое применение наследования не рекомендуется. Наследование должно использоваться только тогда, когда речь идет о наследовании от суперкласса некоторых деталей реализации (операций, атрибутов, отношений). – Это одна из разновидностей многократного использования.

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

Уточнение отношений, выявленных на этапе анализе

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

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

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

Пример агрегации Пример агрегации: компьютер очень слабо взаимосвязан со своим периферийным оборудованием. – Периферийные устройства могут появляться и исчезать, могут совместно использоваться с другими компьютерами. – Они не «принадлежат» конкретному компьютеру.

Пример композиции Пример композиции: дерево тесно взаимосвязано со своими листьями. – Листья принадлежат только одному дереву, ими нельзя поделиться с другими деревьями, и когда дерево умирает, листья умирают вместе с ним.

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

Пример агрегации Из данного примера видно, что: – компьютер (класс Computer) может быть присоединен к 0 или более принтерам (класс Printer); – в любой момент времени принтер соединен с 0 или 1 компьютером; – в ходе времени конкретный принтер может использоваться многими компьютерами; – принтер может существовать, даже если не подключен ни к одному компьютеру; – принтер фактически не зависит от компьютера.

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

Агрегация транзитивна Транзитивность означает, что если C является частью B, и B является частью A, тогда C также является частью A.

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

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

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

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

Согласно этой модели домашний компьютер можно рассматривать как совокупность следующих частей: – Mouse (мышь), – Keyboard (клавиатура), – CPU (центральный процессор), – Monitor (монитор) и – два объекта Speaker (колонка). CPU, в свою очередь, может быть смоделирован как совокупность различных аппаратных компонентов, таких как – RAM (ОЗУ), – HardDrive (жесткий диск) – и т. д.

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

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

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

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

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

Когда использовать композицию и атрибуты 1.Типом атрибута может быть простой тип данных. – В некоторых ОО языках программирования (например, C++ и Java), есть простые типы (например, int и double), которые не являются классами. – Простые типы можно моделировать как классы (с использованием стереотипа «primitive»), но это сильно загромождает модель. – Простые типы всегда должны моделироваться как атрибуты. 2.Существуют определенные, широко используемые вспомогательные классы, такие как Time, Date и String. – Если каждый раз моделировать эти классы с помощью отношения композиции, то очень скоро модели становятся абсолютно непонятными. – Намного лучше моделировать такие классы как атрибуты.

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

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

После того как принято решение о применении агрегации или композиции, необходимо действовать следующим образом: 1.добавить в ассоциации кратности и имена ролей, если они отсутствуют; 2.выбрать, какой конец ассоциации является целым, а какой – частью; посмотреть на кратность связи со стороны целого; если это «0..1» или 1, вероятно, можно использовать композицию; в противном случае должна использоваться агрегация; 3.добавить возможность навигации от целого к части – ассоциации уровня проектирования должны быть однонаправленными.

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

Можно рассмотреть возможность превращения Party- Identifier (идентификатор команды) в атрибут класса Party (команда) – если PartyIdentifier не является особо важным классом. Упрощает диаграмму, но имеет и недостаток: – нельзя показать атрибуты или операции, принадлежащие классу PartyIdentifier.

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

Ассоциации «многие-к-одному» Если циклов в ассоциации «многие-к-одному» не обнаружены, то ассоциацию «многие-к-одному» этапа анализа можно уточнять до агрегации, как показано на рис. – один объект Currency (валюта) совместно используется многими объектами Money (деньги). – правильно отражает отношение между деньгами и валютой: деньги – это сумма в некоторой валюте.

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

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

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

Операции классов-коллекций У всех таких классов есть операции для: 1.добавления объектов в коллекцию; 2.удаления объектов из коллекции; 3.извлечения ссылки на объект, находящийся в коллекции; 4.обход коллекции, т. е. проход по коллекции от первого объекта до последнего.

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

Пример использования коллекции На рис. показана ассоциация один-ко-многим уровня анализа, реализованная с помощью класса-коллекции Vector (класс стандартной библиотеки Java java.util). Как правило, между целым (классом Order (заказ)) и классом Vector устанавливается отношение композиции, поскольку Vector обычно является всего лишь частью реализации целого и не может существовать вне него. Однако между классом Vector и его частями (OrderLine (строка заказа)) может существовать отношение агрегации или композиции. Если целое несет ответственность за жизненный цикл частей, как в данном примере, можно использовать композицию. В противном случае должна использоваться агрегация.

С точки зрения моделирования с использованием коллекций существуют следующие основные способы: 1.Явное моделирование «класса-коллекции». 2.Задание конкретного «класса-коллекций» для реализации ассоциации «один-ко-многим». 3.Указание использования коллекций, но без указания конкретного класса реализации. 4.Уточнение отношения «один-ко-многим» до «классов-коллекций» не выполняется – решение этой задачи передается программистам.

1. Явное моделирование класса-коллекции Его преимущество в чрезвычайной детализации, однако есть и большой недостаток – «загроможденность» проектной модели. Если ассоциация «один-ко-многим» заменяется «классом- коллекции», модель быстро становится очень раздутой. Выбор класса-коллекции обычно является тактическим решением реализации, и право это сделать можно передать программистам. Рекомендуется заменять ассоциации «один-ко-многим» конкретными «классами-коллекций», только если выбор коллекции является стратегически важным.

2. Задание конкретного «класса-коллекций» для реализации ассоциации «один-ко-многим» Многие инструменты моделирования, генерирующие код, позволяют назначать конкретный «класс- коллекции» для каждой ассоциации «один-ко- многим». Обычно это осуществляется путем добавления в ассоциацию помеченных значений, определяющих свойства генерации кода для данного отношения. Пример показан на схеме: на соответствующем конце отношения указано свойство {Vector}. – используется только именная часть помеченного значения – часть «значение» в данном случае является излишней.

3. Указание использования коллекций, но без указания конкретного класса реализации Используемый тип коллекции – часто тактическое, а не стратегическое решение, которое может быть принято программистами во время реализации. Этот вариант хорош тем, что сохраняется лаконичность модели, и программистам могут быть предоставлены подсказки по поводу того, какой «класс-коллекции» должен использоваться. Однако такой подход обычно исключает автоматическую генерацию кода.

UML обозначения для коллекций UML предоставляет стандартные свойства, которые могут применяться к кратностям для обозначения требуемой семантики коллекции. Упорядоченность - определяет, как располагаются элементы в коллекции: в строгом порядке относительно друг друга или нет. Уникальность - определяет единичность каждого объекта коллекции. Для отношения один-ко-многим по умолчанию применяется семантика {unordered, unique} ({неупорядоченный, уникальный}). СвойствоСемантика {ordered}Существует строгий порядок расположения элементов коллекции. {unordered}Элементы в коллекции располагаются в произвольном порядке. {unique}Все элементы коллекции уникальны – один и тот же объект появляется в коллекции максимум один раз. {nonunique}В коллекции допускается дублирование элементов.

Сочетания свойств упорядочения и уникальности создают набор коллекций: СвойствоКоллекция OCL {unordered, nonunique}Bag (мультимножество) {unordered, unique}Set (множество) {ordered, unique}OrderedSet (упорядоченное множество) {ordered, nonunique}Sequence (последовательность)

Конкретизация отношений Некоторые типы отношений являются исключительно элементами анализа и не поддерживаются напрямую ни одним из широко используемых ОО языков программирования. Процесс реализации таких отношений уровня анализа называют конкретизацией (reification) (т. е. превращение в нечто конкретное). Конкретизации подвергаются следующие отношения уровня анализа: – ассоциации «многие-ко-многим»; – двунаправленные ассоциации; – «классы-ассоциации».

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

Пример ассоциации «многие-ко-многим» В данном примере отношение allocation (распределение) было конкретизировано в класс Allocation. Это превращает ассоциацию «многие-ко- многим» в два отношения агрегации.

Исходя из требований, предъявляемых к системе, было принято решение, что Resource (ресурс) – это целое. Система главным образом занимается управлением потоками работ, ассоциированными с Resource, т. е. является «ресурсо-центричной». Однако если бы система была «задаче- центричной», целым был бы сделан объект Task (задача), что изменило бы направление отношений, представленных на рисунке.

Также было решено возложить ответственность за жизненный цикл объектов Allocation на Resource, и поэтому используется отношение композиции. Если система пытается представить обе точки зрения, ее можно было бы назвать ориентированной на распределение ресурсов. Тогда был бы введен новый объект (возможно, AllocationManager (менеджер распределения)), обслуживающий список объектов Allocation, каждый объект которого указывает как на объект Resource, так и на объект Task.

Двунаправленные ассоциации Часто необходимо смоделировать обстоятельства, в которых – объект а класса А использует сервисы объекта b класса В, и – объекту b необходимо делать обратный вызов и использовать сервисы объекта а. Например: управление GUI Window с одним или более объектами Button, где – каждому объекту Button надо выполнять обратный вызов и – использовать сервисы Window, которому они принадлежат.

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

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

Если бы между B и A было применено отношение агрегации, объект b был бы частью (через композицию или агрегацию) объекта а, и объект а был бы частью (через агрегацию) объекта b. Такое замкнутое владение, конечно же, нарушает асимметричность агрегации. Двунаправленные ассоциации также имеют место тогда, когда целое передает ссылку на себя в качестве параметра одной из операций части или когда часть в одной из своих операций создает экземпляр целого. В этих случаях необходимо использовать отношение зависимости от части к целому, а не ассоциацию.

Если бы между B и A было применено отношение агрегации, – объект b был бы частью (через композицию или агрегацию) объекта а, и – объект а был бы частью (через агрегацию) объекта b. Такое замкнутое владение, нарушает асимметричность агрегации.

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

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

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

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

Шаблоны проектирования

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

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

Понятие шаблона (pattern) впервые было предложено Christopher Alexander для разработки архитектуры зданий и описаны в его книге – «The Timeless Way of Building» (Alexander 1979). «Любой паттерн описывает задачу, которая снова и снова возникает в нашей работе, а также принцип ее решения, причем таким образом, что это решение можно потом использовать миллион раз, ничего не изобретая заново» (Александр Кристофер, архитектор). Такое определение верно и в отношении паттернов объектно-ориентированного проектирования.

Понятие паттерна (шаблона) При ООП решения описываются в терминах объектов и интерфейсов, а не стен и дверей, но в обоих случаях смысл паттерна - предложить решение определенной задачи в конкретном контексте. Под паттернами ОО проектирования понимается описание взаимодействия объектов и классов, адаптированных для решения общей задачи проектирования в конкретном контексте. В области ПО использование шаблонов проектирования было предложено и развито Gamma, Helms, Johnson и Vlissides в их книге «Design Patterns (1995)», в которой они описали 23 шаблона проектирования. – Э. Гамма, Р. Хелм, Р. Джонсон, Д. Влиссидес «Приемы объектно- ориентированного проектирования (Паттерны проектирования)», «ДМК Пресс», СПб, 2010, 368 с.

Типы шаблонов Шаблоны проектирования (design patterns) – Шаблон проектирования это небольшая взаимодействующих объектов. Архитектурные шаблоны (architectural patterns). – Архитектурные шаблоны это шаблоны описывающие взаимодействие более крупных элементов, чем шаблоны проектирования. – Они предназначенные для определения структуры больших подсистем программной системы. Шаблоны анализа (analysis patterns). – Fowler (2002) обнаружил сходства в ходе анализа приложений, разрабатываемых для разных предметных областей. – Он описал часто повторяющиеся шаблоны найденные в ОО анализе с помощью статических моделей, представленных в виде диаграмм классов. Идиомы (idioms).

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

Каталог паттернов проектирования 1.Abstract Factory (абстрактная фабрика) – Предоставляет интерфейс для создания семейств, связанных между собой, или независимых объектов, конкретные классы которых неизвестны. 2.Adapter (адаптер) – Преобразует интерфейс класса в некоторый другой интерфейс, ожидаемый клиентами. – Обеспечивает совместную работу классов, которая была бы невозможна без данного паттерна из-за несовместимости интерфейсов. 3.Bridge (мост) – Отделяет абстракцию от реализации, благодаря чему появляется возможность независимо изменять то и другое. 4.Builder (строитель) – Отделяет конструирование сложного объекта от его представления, позволяя использовать один и тот же процесс конструирования для создания различных представлений. 5.Chain of Responsibility (цепочка обязанностей) – Можно избежать жесткой зависимости отправителя запроса от его получателя, при этом запросом начинает обрабатываться один из нескольких объектов. – Объекты-получатели связываются в цепочку, и запрос передается по цепочке, пока какой-то объект его не обработает.

Каталог паттернов проектирования 6.Command (команда) – Инкапсулирует запрос в виде объекта, позволяя тем самым параметризо- вывать клиентов типом запроса, устанавливать очередность запросов, протоколировать их и поддерживать отмену выполнения операций. 7.Composite (компоновщик) – Группирует объекты в древовидные структуры для представления иерархий типа «часть-целое». – Позволяет клиентам работать с единичными объектами так же, как с группами объектов. 8.Decorator (декоратор) (173) – Динамически возлагает на объект новые функции. – Применяются для расширения имеющейся функциональности и являются гибкой альтернативой порождению подклассов. 9.Facade (фасад) (183) – Предоставляет унифицированный интерфейс к множеству интерфейсов в некоторой подсистеме. – Определяет интерфейс более высокого уровня, облегчающий работу с подсистемой.

10.Factory Method (фабричный метод) – Определяет интерфейс для создания объектов, при этом выбранный класс инстанцируется подклассами. 11.Flyweight (приспособленец) – Использует разделение для эффективной поддержки большого числа мелких объектов. 12.Interpreter (интерпретатор) – Для заданного языка определяет представление его грамматики, а также интерпретатор предложений языка, использующий это представление. 13.Iterator (итератор) – Дает возможность последовательно обойти все элементы составного объекта, не раскрывая его внутреннего представления. 14.Mediator (посредник) – Определяет объект, в котором инкапсулировано знание о том, как взаимодействуют объекты из некоторого множества. – Способствует уменьшению числа связей между объектами, позволяя им работать без явных ссылок друг на друга. – Это, в свою очередь, дает возможность независимо изменять схему взаимодействия.

15. Memento (хранитель) – Позволяет, не нарушая инкапсуляции, получить и сохранить во внешней памяти внутреннее состояние объекта, чтобы позже объект можно было восстановить точно в таком же состоянии. 16.Observer (наблюдатель) – Определяет между объектами зависимость типа один-ко- многим, так что при изменении состоянии одного объекта все зависящие от него получают извещение и автоматически обновляются. 17.Prototype (прототип) – Описывает виды создаваемых объектов с помощью прототипа и создает новые объекты путем его копирования. 18.Proxy (заместитель) – Подменяет другой объект для контроля доступа к нему.

19. Singleton (одиночка) – Гарантирует, что некоторый класс может иметь только один экземпляр, и предоставляет глобальную точку доступа к нему. 20. State (состояние) – Позволяет объекту варьировать свое поведение при изменении внутреннего состояния. При этом создается впечатление, что поменялся класс объекта. 21. Strategy (стратегия) – Определяет семейство алгоритмов, инкапсулируя их все и позволяя подставлять один вместо другого. Можно менять алгоритм независимо от клиента, который им пользуется. 22. Template Method (шаблонный метод) – Определяет скелет алгоритма, перекладывая ответственность за некоторые его шаги на подклассы. Позволяет подклассам переопределять шаги алгоритма, не меняя его общей структуры. 23. Visitor (посетитель) – Представляет операцию, которую надо выполнить над элементами объекта. Позволяет определить новую операцию, не меняя классы элементов, к которым он применяется.