Студопедия

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника



ТЕМА: UML. Элементы графической нотации диаграммы кооперации.




Читайте также:
  1. A. Элементы резания при точении
  2. B) Элемент диаграммы, показывающий название и маркеры данных диаграммы
  3. II. Материальные элементы (МЭ)
  4. III.4.3) Виды и элементы вины.
  5. V1: 4.Элементы поражения слизистой оболочки полости рта (СОПР) и красной каймы губ
  6. А) Основные элементы измерительных приборов
  7. Абстрактные, корневые, листовые и полиморфные элементы
  8. АВТОНОМИЯ ВОЛИ СТОРОН) И ДИСПОЗИТИВНЫЕ ЭЛЕМЕНТЫ
  9. Активные элементы схемы замещения
  10. Алгоритм 2. Визуальный анализ диаграммы рассеяния, выявление и фиксация аномальных значений признаков, их удаление из первичных данных

 

Литература: 1. Леоненков А. В. Самоучитель UML. - 2-е изд.

2. Бабич А. Введение в UML. //курс НОУ «ИНТУИТ».

 

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

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

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

Для одного варианта использования может быть построено несколько диаграмм взаимодействия.

Обычно диаграммы кооперации применяются для того, чтобы:

1. показать набор взаимодействующих объектов в реальном окружении "с высоты птичьего полета";

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

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

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

Говоря о диаграммах кооперации, часто упоминают два "уровня" таких диаграмм - уровень экземпляров(примеров, Instance-Level) и уровень спецификации (Specification-Level). Уровень экземпляров отображает взаимодействия между объектами (экземплярами классов); такая диаграмма обычно создается, чтобы исследовать внутреннее устройствообъектно-ориентированной системы. Уровень же спецификации используется для изучения ролей, исполняемых в системе основными классами.



Кооперация.

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

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

Понятие кооперации – одно из фундаментальных в языке UML. Цель самой кооперации состоит в том, чтобы специфицировать особенности реализации отдельных вариантов использования или наиболее значимых операций в системе. Кооперация определяет структуру поведения системы в терминах взаимодействия участников этой кооперации и часто реализует некоторый паттерн(шаблон проектирования).

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



Рис. 1. Первый способ изображения кооперации.

Второй способ показывает прикрепленные к объектам (классам) роли в рамках данной кооперации. Назначение роли изображается пунктирной линией со стрелкой на конце, направленной в сторону объекта. Имя роли указывается на конце линии, рядом с объектом (рис. 2).

Рис. 2. Второй способ изображения кооперации.

На диаграмме, изображенной на рисунке 2, также показана генерализация и кооперации, и самих исполнителей.

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

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

Объекты и их графическое изображение.

Определение 2. Объект (object) - сущность с хорошо определенными границами и индивидуальностью, которая инкапсулирует состояние и поведение.

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

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

Рассмотрим особенности семантики и графического представления объектов на диаграммах.

Для диаграмм кооперации полное имя объекта в целом представляет собой строку текста, разделенную двоеточием и записанную в формате:

<собственное имя объекта> / <Имя роли класса>:<Имя класса>

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

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

Имя класса – это имя одного из классов, представленного на диаграмме классов.

Собственное имя объекта должно начинаться со строчной буквы.

Имя объекта, имя роли с символом "/" или имя класса могут отсутствовать. Однако двоеточие всегда должно стоять перед именем класса, а косая черта – перед именем роли.

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

1. main : Form – объект с собственным именем main, экземпляр класса Form.

2. : Form – анонимный объект, экземпляр класса Form.

3. фирма : (или просто фирма) - объект-сирота с собственным именем фирма.

4. фирма / Адресат : Клиент - объект с собственным именем фирма, экземпляр класса Клиент, играющий роль Адресат.

5. / Адресат : Клиент - анонимный объект, экземпляр класса Клиент, играющий роль Адресат.

6. object1 / Обработчик запросов - объект -сирота с собственным именем object1, играющий роль Обработчик запросов.

7. / Обработчик запросов - анонимный объект и одновременно объект -сирота, играющий роль Обработчик запросов.

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

Примеры изображения объектов на диаграммах приводятся на рис. 3.

Рис. 3. Примеры графических изображений объектов на диаграммах.

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

Отсутствовать может и имя класса – такой объект называется сиротой. Для него записывается только собственное имя объекта, двоеточие не ставится (рис. 3 г).

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

Для отдельных объектов (рис. 3 д, е) могут быть дополнительно указаны роли, которые они играют в кооперации.

В контексте языка UML все объекты делятся на две категории: пассивные и активные.

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

Активный объект (active object) имеет собственный процесс управления и может инициировать деятельность по управлению другими объектами. На диаграмме кооперации он обозначается прямоугольником с утолщенными границами (рис. 4). Каждый активный объект является владельцем определенного процесса управления. В данном фрагменте диаграммы кооперации активный объект а:Клиент является инициатором открытия счета, который представлен анонимным объектом :Счет.

Рис. 4. Графическое изображение активного объекта (слева) на диаграмме кооперации.

Также существуют понятия мультиобъекта и составного объекта.

Определение 3. Мультиобъект (multiobject) - это множество анонимных объектов, которые могут быть образованы на основе одного класса.

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

Рис. 5. Графическое изображение мультиобъектов на диаграмме кооперации.

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

Рис. 6. Диаграмма кооперации, показывающая выбор адреса клиента для отправки электронного письма.

Определение 3. Составной объект (composite object) или объект-композит предназначен для представления объекта, имеющего собственную структуру и внутренние потоки (нити) управления.

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

Рис. 7. Графическое изображение составного объекта на диаграмме кооперации.

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

Связи на диаграмме кооперации.

Определение 4. Связь (link) - любое семантическое отношение между некоторой совокупностью объектов.

Связь как элемент языка UML является экземпляром или примером произвольной ассоциации и может иметь место между двумя и более объектами. Бинарная связь на диаграмме кооперации изображается отрезком сплошной линии, соединяющей два прямоугольника объектов (рис. 6). На концах этой линии дополнительно могут быть явно указаны имена ролей соответствующей ассоциации.

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

Примеры связей с различными стереотипами изображены на рис. 8. Здесь представлена обобщенная схема компании с именем «с», которая состоит из департаментов (анонимный мультиобъект класса Департамент). В последние входят сотрудники (анонимный мультиобъект класса Сотрудник). Рефлексивная связь со стереотипом ˂˂self˃˃ указывает на то, что руководитель департамента является одновременно и его сотрудником. То, что «с» не является многонациональной распределенной компанией, указывается с помощью стереотипа ˂˂local˃˃.

Рис. 8. Графическое изображение связей с различными стереотипами.

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

Сообщения и их графическое изображение.

Определение 1. Сообщение (message) - спецификация передачи информации от одного элемента модели к другому с ожиданием выполнения определенных действий со стороны принимающего элемента.

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

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

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

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

Рис. 9. Графическое изображение различных типов сообщений на диаграмме кооперации.

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

2. Сплошная линия с V-образной стрелкой (рис. 9 б) обозначает асинхронное сообщение в простом потоке управления. В этом случае клиент передает асинхронное сообщение и продолжает выполнять свою деятельность, не ожидая ответа от сервера.

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

Каждое сообщение может быть помечено строкой текста, которая имеет следующий формат:

<Предшествующие сообщения> / <Порядковый номер сообщения>:

<Возвращаемое значение := имя сообщения> <(Список аргументов)>

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

Порядковый номер сообщения - это разделенный точками список чисел, после которого записывается двоеточие. Каждое из чисел представляет отдельный уровень вложенности номера. Например, объект отправил другому объекту сообщение с номером 1. Когда объект-получатель в свою очередь отправляет сообщения другим объектам, они получают номера 1.1, 1.2 и т. д. Иногда нужно показать одновременную отправку сообщений. Чтобы отметить параллельные потоки сообщений, их номера предваряют буквами A, B, C, D и т. д. Необходимость номера сообщения объясняется очень просто - в отличие от диаграммы последовательностей, время на диаграмме взаимодействия не показывается в виде отдельного измерения. Поэтому последовательность передачи сообщений можно указать только с помощью их нумерации.

После номера можно указать рекуррентность (показывает итеративный или условный характер выполнения передачи сообщений):

1. *[Предложение-итерация] - используется для записи итеративного (многократного) выполнения соответствующего выражения. Итерация представляет последовательность сообщений одного уровня вложенности. В общем случае предполагается, что итерации выполняются последовательно. Если необходимо отметить возможность параллельного выполнения итераций, то для этой цели в языке UML используется символ "*||". Предложение-итерация может быть опущено, если количество итераций никак не специфицируется. Наиболее часто предложение-итерация записывается на псевдокоде или языке программирования. В языке UML формат записи этого предложения строгим образом не определен.

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

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

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

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

В языке UML определены следующие стереотипы сообщений:

1. <<call>> (вызвать) – сообщение, требующее вызова операции или процедуры объекта-получателя. Если сообщение с этим стереотипом рефлексивное, то оно инициирует локальный вызов операции у пославшего это сообщение объекта.

2. <<return>> (возвратить) – сообщение, возвращающее значение выполненной операции или процедуры вызвавшему ее объекту. Значение результата может инициировать ветвление потока управления.

3. <<create>> (создать) – сообщение, требующее создания другого объекта для выполнения определенных действий. Созданный объект может стать активным (ему передается поток управления), а может остаться пассивным.

4. <<destroy>> (уничтожить) – сообщение с явным требованием уничтожить соответствующий объект. Посылается в том случае, когда необходимо прекратить нежелательные действия со стороны существующего в системе объекта, либо когда объект больше не нужен и должен освободить задействованные им системные ресурсы.

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

Пример. На рисунке 10 представлена диаграмма кооперации, описывающая покупку товаров. Сообщение с номером 1.1 предполагает итеративное выполнение для формирования списка заказанных товаров (используется *). Также анонимный объект класса Order отправляет сам себе рефлексивное сообщение с номером 1.2, инициируя выполнение вычисления итоговой суммы заказа. На диаграмме показано, что результат этого сообщения будет присвоен переменной (атрибуту) orderTotal (возвращаемое значение).

 

 

Рис. 10. Диаграмма кооперации, описывающая покупку товаров.

Пример. На рисунке 11 представлена диаграмма кооперации, на которой отображено выполнение сообщения с номером 2 параллельно двумя объектами - nsLights и ewLights (А2, В2). Сообщение с номером 3 также выполняется параллельно двумя объектами - nsSignals и ewSignals (С3, D3).

 

Рис. 11. Диаграмма кооперации, описывающая параллельные потоки сообщений.

Рекомендации по построению диаграмм кооперации.

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

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

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

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

Если же хочется еще больше детализировать диаграмму, можно ввести временные ограничения на выполнение отдельных действий. Впрочем, для простых асинхронных сообщений временные ограничения, скорее всего, не нужны. А вот необходимость синхронизации сложных потоков управления часто требует использования таких ограничений. Запись их должна следовать правилам языка объектных ограничений (OCL, Object Constraint Language).

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

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

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

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

 

 

Лекция 11

 


Дата добавления: 2015-04-11; просмотров: 62; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2020 год. (0.022 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты