Помощничек
Главная | Обратная связь


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

Технология моделирования UML



 

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

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

В результате многолетних исследований был разработан и опробован так называемый объектно-ориентированный подход (ООП) (в 1967 году создан первый язык, основанный на данном подходе - Simula67, в 1983 году - язык C++). Главная причина возникновения ООП связана с поиском простых путей для создания сложных программ. ООП наследует лучшие черты структурного программирования и комбинирует их с некоторыми новыми подходами. Одно из основных преимуществ ООП по сравнению с более ранними методами построения программных систем - тесная связь данных и кода, работающего с ними. То есть, данные стали объединяться со соответствующими операциями их обработки в некие структуры, называемые объектами. В ООП были реализованы механизмы, позволяющие:

1) описывать структуру объекта;

2) описывать действия с объектами;

3) использовать специальные правила наследования объектов;

4) передавать сообщения между объектами.

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

В течение последних нескольких лет при поддержке консорциума Object Managing Group (OMG) специалистами фирм Rational Software Corporation и др. разрабатывался Унифицированный Язык Моделирования (UML - Unified Modeling Language), который предоставляет объектно-ориентированный метод разработки ПО с поддержанием объектно-ориентированной реализации.

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

 

1.2 Основные компоненты UML

 

Основные компоненты, составляющие UML, включают описание семантики UML (то есть, описание составляющих единиц языка), его графическую нотацию (то есть, совокупность графических объектов, которые используются в моделях) и описание дополнительных понятий, позволяющих расширить смысл основных понятий языка. Документация по UML содержит подробное описание этих компонент и вместе с формальным описанием UML в виде семи pdf-файлов представлена на сайте Rational Software [14]. Описание языка, представленное в данной работе, является сокращенным, но содержит все основные понятия языка.

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

1) Диаграммы классов (class diagrams).

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

2) Диаграммы вариантов использования (use case diagrams).

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

3) Диаграммы взаимодействия (interaction diagrams).

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

4) Диаграммы последовательности(sequence diagrams).

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

5) Кооперативные диаграммы (collaboration diagrams).

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

6) Диаграммы состояний (state diagrams).

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

7) Диаграммы деятельностей (activity diagrams).

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

8) Диаграммы размещения (deployment diagrams).

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

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

 

1.3 Диаграммы классов (class diagrams)

 

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

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

Итак, Класс - это группа сущностей (объектов), обладающих сходными свойствами, а именно, данными и поведением.

ООП характеризуется тремя основными свойствами:

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

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

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

1.3.1 Назначение диаграмм классов

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

Класс

 

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

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

 

 

Рисунок 1 - Пример изображения класса

 

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

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

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

<имя пакета>::<имя класса>

Так как иерархия пакетов может иметь глубину вложенности большую, чем 1, то путь к классу может содержать более чем один пакет, при этом путь начинается от корня иерархии пакетов:

<имя пакета1>::<имя пакета2>::...::<имя пакетаN>::<имя класса>

В секции имени класса могут находиться (по порядку сверху вниз):

1) Тип класса (и/или иконка типа в правом верхнем углу) - необязательное поле, опускается, если речь идет о не специфицированном классе.

2) Имя класса (если класс абстрактный - курсивом).

3) Дополнительные свойства - имя автора и т.п. (необязательное поле).

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

 

1.3.3 Атрибут

Атрибут (attribute) - это элемент данных класса, т.е. элемент данных, который содержится в объекте, принадлежащем описываемому классу.

У атрибута должен быть тип (type expression), который может представлять собой простой тип или быть сложным, как например:

CArray<CString *, CPoint *>

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

Атрибут изображается в виде текстовой строки, отражающей различные его свойства:

<признак видимости><имя>::<тип>=<значение по умолчанию>{свойства}

Признак видимости имеет С++ семантику видимости членов класса:

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

2) Защищенный атрибут (protected) (обозначается символом #) означает, что к атрибуту имеют доступ только методы данного класса и его потомков.

3) Секретный атрибут (private) (обозначается символом -) означает, что атрибут доступен только методам класса.

4) Символ области видимости может изображаться ключевым словом “public", "private” или “protected” или может быть опущен. Это означает, что область видимости не показывается (а не то, что она не определена или “public” по умолчанию).

Имя - это идентификатор, представляющий имя атрибута.

Тип - зависящее от языка реализации описание типа атрибута.

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

Свойства - строка дополнительных свойств элемента (необязательная часть). Если свойства не указываются, скобки {} опускаются. Примером свойства может служить имя автора:

{Author = Smith}

По умолчанию атрибут является изменяемым. Указав в его свойствах пометку {frozen} можно объявить атрибут неизменяемым.

Для атрибута можно указывать его множественность. Если она не обозначена, то предполагается, что атрибут может хранить ровно одно значение. Множественность может быть определена в квадратных скобках сразу после имени атрибута:

coords[3]: integer

 

1.3.4 Операция

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

Операция изображается текстовой строкой, имеющей следующую грамматику:

<признак видимости><имя>(список параметров):<тип выражения, возвращающего значения> {свойства}

Признак видимости, имя и свойства имеют тот же смысл, что и для атрибута.

Список параметров - список формальных параметров, разделенных запятыми: <имя>:<тип>=<значение по умолчанию>

Имя - имя параметра.

Тип - зависящее от языка реализации описание типа параметра.

Значение по умолчанию - значение параметра по умолчанию.

В последней версии UML предусмотрена также возможность указания вида параметра (входной, выходной или смешанного типа).

Тип выражения, возвращающего значения - зависящее от языка реализации описание типа значения, возвращаемого функцией. Если оно не указано, то предполагается, что функция не возвращает значения (void для C/C++).

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

createObject(void): PObject

Операция, не изменяющая состояние системы, помечается следующим образом: в список свойств операции помещается свойство {query}.

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

"constructors"

CRect(CPoint left_up, CPoint right_down)

CRect(left:Integer, top:Integer, right:Integer, bottom:Integer)

"Data access"

GetLeftUp(): CPoint

SetLeftUp(CPoint lup)

GetRightDown():CPoint

SetRightDown (CPoint rdn)

...

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

"Get-Data functions"

GetLeftUp(): CPoint

SetLeftUp(CPoint lup)

"Set-Data functions"

GetRightDown():CPoint

SetRightDown (CPoint rdn)

...

У каждой секции прямоугольника класса может быть имя. При этом, так как секция "Имя класса" обязательна, то ее имя не указывается (рис.2).

 

Рисунок 2 - Пример изображения класса

 

1.3.5Объект

 

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

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

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

<имя объекта>:<имя класса>

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

display_window : WindowingSystem : : GraphicWindows : : Window

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

Вторая секция содержит в себе список имен атрибутов с их типами и значениями. Каждая строка из списка имеет синтаксис:

<имя атрибута>:<тип>=<значение>

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

Рисунок 3 - Объекты

Составной объект

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

Составной объект представляется на диаграмме также как и просто объект. Имя объекта также располагается в верхней секции прямоугольника, а в нижней секции вместо атрибутов объекта располагаются части составного объекта (рис.4).

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

Рисунок 4 - Составной объект


Активный объект

 

Активный объект (active object) имеет возможность инициировать действие. Пассивный объект может содержать в себе данные, но не может инициировать действия. Однако пассивный объект может посылать сообщения в процессе обработки запроса, который он получил.

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

 

Рисунок 5 - Активный составной объект

 




Поиск по сайту:

©2015-2020 studopedya.ru Все права принадлежат авторам размещенных материалов.