Методические указания по выполнению лабораторных занятий



бет66/102
Дата01.09.2022
өлшемі3,94 Mb.
#38357
түріМетодические указания
1   ...   62   63   64   65   66   67   68   69   ...   102
Байланысты:
Технология проектирования программных систем

Вопросы для самопроверки
1. Перечислите элементы диаграмм взаимодействия.
2. Перечислите и дайте характеристику видам сообщений.
3. Как обозначается активность объекта на диаграмме последовательности.
4. Какие отношения могут быть между пакетами?
5. Назовите способы группировки классов по пакетам.
6. Назовите основные правила и рекомендации по разработке диаграмм взаимодействия.


Лекция № 14. МОДЕЛЬ ПРОЕКТИРОВАНИЯ
14.1. Назначение и состав
14.2. Назначение и состав диаграммы классов
14.3. Правила и рекомендации по разработке диаграммы классов
14.4. Пример построения диаграммы классов
14.5. Шаблоны проектирования
Вопросы для самопроверки
14.1. Назначение и состав
Назначение модели проектирования заключается в создании полного детализированного описания внутренней архитектуры и алгоритмов работы системы. Рекомендуется разрабатывать данную модель без привязки к конкретным языкам программирования, с помощью которых будет создаваться программный продукт, т. е. разрабатывать логическую модель. Стоит оговориться, что создать модель без оглядки на используемые языки программирования невозможно, но, по крайней мере, необходимо стремиться к этому.
Построение этой модели необходимо:
 для уточнения внутренней архитектуры и вариантов использования системы;
 уточнения требований;
 определения детализированных алгоритмов работы системы в целом и ее отдельных элементов.
Согласно Унифицированному процессу [29] последовательность действий при построении модели анализа можно выразить следующей схемой (рис. 14.1).

Рис. 14.1. Обобщенная схема технологического процесса «Проектирование»
При разработке модели анализа рекомендуется построить следующие диаграммы (основные артефакты):
 классов;
 деятельности.
Основное внимание на данной стадии уделяется проектированию классов (их атрибутов и операций), компоновке классов в подсистемы и определению интерфейсов между классами и подсистемами. Детальное описание операций и взаимодействия между классами выполняется с помощью диаграмм деятельности, описывающих алгоритмы работы. В разработке алгоритмов, специфичных для предметной области, непосредственное участие должны принимать эксперты-технологи. 
14.2. Назначение и состав диаграммы классов
Состав диаграммы классов аналогичен составу диаграммы классов анализа. В то же время классы анализа должны пройти процедуру строгой экспертизы на предмет их возможной декомпозиции на более мелкие и специализированные классы. При построении диаграммы окончательно должны быть определены атрибуты и операции классов.
Особенности задания атрибутов, методов и отношений между классами будут иллюстрироваться с учетом специфики (синтаксиса и семантики) языка программирования Java.
Графически класс отображается в виде прямоугольника, который может быть разделен горизонтальными линиями на секции. В этих секциях указывается имя, атрибуты (свойства) и операции (методы) (рис. 14.2).

Имя


Имя


Имя

Атрибуты

Атрибуты

Операции

Рис. 14.2. Способы отображения класса
Секция атрибутов выделяется горизонтальной линией, даже если у класса отсутствуют атрибуты (характерно для классов-интерфейсов). На рис. 14.3 приведен пример определения интерфейса без атрибутов, выполняющего доступ к характеристикам отрезка пути с однородными уровнями допускаемой скорости.

«interface»
VdopRow


getKmN()
getKmK()
getVkonLoc()
getVkonVag()

Рис. 14.3. Пример класса без атрибутов (интерфейса)
С точки зрения структурного подхода, атрибуты – это переменные, а методы – это функции, описанные в теле класса. Они могут быть доступны или не доступны для изменения (атрибуты) или выполнения (методы) внешними объектами.
Обязательным элементом обозначения класса на диаграмме является его имя. Оно должно быть уникальным в пределах пакета. Если класс является абстрактным, то его имя пишется курсивом. Абстрактный класс – это класс, на основе которого нельзя создать объекты. Такие классы используются в качестве шаблона для дочерних классов при наследовании.
В секции имени класса может быть указан стереотип (например, «entity», «boundary», «interface» и т. п.).
Во второй секции каждому атрибуту соответствует отдельная строка со следующей спецификацией:
[видимость] имя [: тип [‘[‘кратность‘]‘] [ = исходное значение]] [‘{‘строка-свойство’}’]
Квадратные скобки означают, что соответствующий элемент спецификации может отсутствовать. Таким образом, при описании обязательным является только имя атрибута.
Видимость (англ. visibility) характеризует возможность чтения и модификации значения атрибута объекта описываемого класса, из объектов других классов. Модификация значения возможна лишь при условии, что атрибут не является константой. Видимость отображается с помощью следующих символов:
 «+» – общедоступный атрибут (англ. public) – доступен для чтения и модификации из объектов любого класса;
 «#» – защищенный атрибут (англ. protected) – доступен только объектам описываемого класса и его потомкам при наследовании;
 «–» – закрытый атрибут (англ. private) – доступен только объектам описываемого класса;
 «~» – пакетный атрибут (англ. package) – доступен только объектам классов, входящих в тот же пакет.
Имя (англ. name) атрибута представляет собой строку текста, которая используется для его идентификации. Оно должно быть уникальным в пределах класса.
Тип (англ. type) атрибута выбирается исходя из семантики значений, которые должны храниться в атрибуте, и, как правило, возможностей целевого языка программирования по представлению этих значений. Он соответствует одному из стандартных типов, определенных в этом языке (например, String, Boolean, Integer, Color и т. д.) или имени класса, на объекты которого в этом атрибуте будет храниться ссылка. Во втором случае класс, имя которого указано в качестве типа, должен быть определен на диаграмме или в модели.
Кратность (англ. multiplicity) атрибута характеризует количество значений, которые можно хранить в атрибуте. Если кратность атрибута не указана, то по умолчанию принимается ее значение, равное 1, т. е. атрибут является атомарным. Такой вариант допускает и отсутствие значения в атрибуте (null). Для атрибута, представляющего собой массив, множество, список и т. п., требуется указание кратности, которая записывается после типа в квадратных скобках. Варианты указания кратности, имеющие смысл, могут быть следующие:
 [0..*] или [*] – количество хранимых значений может принимать любое положительное целое число, большее или равное 0. Такой вариант задания кратности характерен для множеств, списков и других атрибутов, допускающих добавление или удаление элементов;
 [0..<число>] – количество хранимых значений, может быть не более указанного числа. Данный вариант применяется при описании массивов фиксированного размера. При этом не обязательно, чтобы все элементы массива имели конкретные значения;
 [0..<число>] [0..<число>] – применяется при описании двумерных массивов. Аналогичным образом можно описать трехмерные, четырехмерные и т.д. массивы.
Исходное значение (англ. default value) служит для задания некоторого начального значения атрибута в момент создания отдельного экземпляра класса (объекта).
Строка-свойство (англ. property-string) описывает особенности реализации атрибута. В частности в строке-свойстве можно указывать следующую информацию:
 {final} или {readOnly} – атрибут является константой, т. е. доступен только для чтения;
 {static} – атрибут в момент выполнения программы в конкретный момент времени будет иметь одно и то же значение для всех объектов класса;
 {transient} – атрибут и его значение при записи объекта в БД или файл (сериализации объекта) не должны запоминаться;
 {derived} – значение атрибута определяется по значениям других атрибутов (производный атрибут);
 {unique} – значения неатомарного атрибута должны быть уникальны;
 {ordered} или {unordered} – значения неатомарного атрибута должны быть отсортированы (ordered) или могут содержаться в произвольном порядке (unordered).
Допускается в строке-свойстве через запятую, указывать сразу несколько модификаторов. Например, {ordered, unique} означает, что элементы массива должны быть уникальны и следовать в строго определенном порядке.
В табл. 6.1 приведены примеры указания спецификации атрибутов и соответствующий им код программы, автоматически генерируемый Case-средством для языка Java.
Таблица 6.1. Примеры указания атрибутов

Спецификация атрибута в UML

Генерируемый код для языка Java

+ name : String

public String name;

+ pi : double = 3.1415 {final, static}

public final static double pi = 3.1415;

– coordinateXY : int[][] = {{1, 1}, {2, 4}, {3, 9}}

private int[][] coordinateXY = {{1, 1}, {2, 4},{3, 9}};

# visible : boolean = true

protected boolean visible = true;

– connect : ConnectDB = null;

private ConnectDB connect = null;

В Java типы, указанные с прописной буквы, называются примитивными (например, double или boolean). Значения атрибутов такого типа непосредственно хранится в объекте. Типы, указанные с заглавной буквы, называются ссылочными (например, String или ConnectDB). В атрибуте такого типа хранится ссылка на объект, созданный на базе соответствующего класса.
В третьей секции указывается перечень методов класса. Можно выделить шесть основных типов методов [14]:
 конструктор – метод, создающий и инициализирующий объект. В Java имя конструктора совпадает с именем класса;
 деструктор – метод, уничтожающий объект. В некоторых языках программирования (в частности в Java) определение деструкторов не требуется, так как очистка памяти от неиспользуемых объектов (сборка мусора) выполняется автоматически;
 модификатор – метод, который изменяет состояние объекта (значения атрибутов). Имена модификаторов начинаются, как правило, со слова set (англ. – установить). Например, установить атрибуту Name новое значение setName(newName : String);
 селектор – метод, который может только считывать значения атрибутов объекта, но не изменяет их. Имена селекторов начинаются, как правило, со слов get (англ. – получить) или is при возврате логического результата. Например, считать значение атрибута Name – getName() или определить видимость на экране элемента графического интерфейса – isVisible();
 итератор – метод, позволяющий организовать доступ к элементам объекта. Например, для объекта, представляющего собой множество Set или список List, это могут быть методы перехода к первому элементу first(), следующему next(), предыдущему previous() и т. п.;
 событие – метод, запускаемый на выполнение автоматически при соблюдении определенных условий.
Тип метода при построении диаграммы классов, как правило, указывается с помощью стереотипа.
Каждому методу соответствует отдельная строка со следующей спецификацией:
[видимость] имя ([список параметров]) [: тип] [‘{‘строка-свойство’}’]
Видимость и имя метода задаются по тем же правилам, что и для атрибутов класса.
Список параметров является перечнем разделенных запятой параметров метода, каждый из которых может быть представлен в следующем виде:
имя : тип [‘[‘кратность‘]‘] [ = значение по умолчанию]] [‘{‘строка-свойство’}’]
Имя и кратность параметра задаются по тем же правилам, что и для атрибутов класса.
Тип параметра – тип значений, которые может принимать параметр.
Значение по умолчанию – значение, которое передается в метод, если при вызове метода данный параметр не определен.
Тип метода – тип результата, возвращаемого методом. Если тип не указан, то метод не возвращает никакого результата и обозначается с помощью модификатора void.
Строка-свойство метода служит для указания специфических свойств метода. В частности в строке-свойстве можно указывать следующую информацию:
 {native} – реализация метода зависит от платформы (операционной системы);
 {abstract} – метод в описываемом классе не имеет тела. Код метода должен быть определен в дочерних классах;
 {synchronized} – при одновременном (параллельном) вызове метода с помощью разных сообщений, должна гарантироваться целостность объекта и корректность обработки информации.
В табл. 6.2 приведены примеры указания спецификации методов и соответствующий им код программы, автоматически генерируемый Case-средством для языка Java.
Таблица 6.2. Примеры указания методов

Спецификация атрибута в UML

Генерируемый код для языка Java

«constructor» + TextFieldInt(value : int, length : int, alligment : int, fontField : Font)

public TextFieldInt(int value, int length, int alligment, Font fontField) { }

+ saveData()

public void saveData() {
return;}

+ isVisible() : boolean

public boolean isVisible() {
return false;}

# init(text : String, icon : Icon)

protected void init(String text, Icon icon) {
return;}

В Java методы, не возвращающие результата, обозначаются с помощью модификатора void. Для остальных методов обязательно должен указываться тип возвращаемого результата. Исключение составляют конструкторы, для которых тип результата не указывается, а возвращаемое значение является ссылкой на объект, который был создан при вызове конструктора.
Отношения, которые можно устанавливать между классами, и их смысловая нагрузка (семантика) были рассмотрены в подразделе по диаграммам классов анализа. Далее иллюстрируется связь между графическим отображением классов и отношений на диаграммах и исходными текстами программ. Современные Case-средства при разработке классов, как правило, работают в режиме синхронизации диаграмм и исходных текстов. Т. е. если меняется диаграмма классов, то это приводит к автоматической корректировке текста программы и наоборот.
Отношение ассоциации означает наличие атрибута, в котором будет храниться ссылка (ссылки) на объект (объекты) класса, в сторону которого направлена стрелка ассоциации (рис. 14.4).
 
Рис. 14.4. Интерпретация ассоциации в тексте программы
Графический символ класса Class_A преобразуется в строки определения самого класса «public class Class_A» и его конструктора «public Class_A() {}». Аналогично для Class_B. Ассоциация от Class_B в сторону Class_A преобразуется в строку «public Class_A object_A;», описывающую атрибут object_A, в котором будет храниться ссылка на объект класса Class_A. Ввиду отсутствия указания кратности отношения, она по умолчанию принимается равной 1. На рис. 14.5 приведен пример двунаправленной ассоциации кратностью более 1.

Рис. 14.5. Интерпретация двунаправленной ассоциации
Наличие двунаправленной ассоциации или ассоциации без стрелок свидетельствует о наличии в обоих классах атрибутов, содержащих ссылки на объекты. Кратность более 1 подразумевает хранение не одной, а нескольких ссылок. Таким образом, один объект класса Class_A будет связан с несколькими объектами класса Class_B. Ссылки на эти объекты будут храниться в массиве object_B[]. Современные Case-средства позволяют вместо массива указывать другие варианты хранения набора объектов, такие как множества, списки, хешированные таблицы и т. д.
Отношения агрегации и композиции являются частными случаями ассоциации. В связи с этим интерпретация этих отношений с точки зрения текста программы совпадает с рассмотренной выше. Окончание агрегации () или композиции () интерпретируется как стрелка (рис. 14.6, а).
Если требуется хранить ссылки на «объекты–части» в «объекте–целом», то с обратной стороны отношения показывается стрелка (рис. 14.6, б).
 
Рис. 14.6. Интерпретация композиции (агрегации) (а);
двунаправленной композиции (агрегации) (б)
Отношение обобщения в тексте программы на языке Java показывается ключевым словом «extends» (англ. – расширяет) в дочернем классе (рис. 14.7).

Рис. 14.7. Интерпретация обобщения
Отношение зависимости не приводит к автоматической генерации кода программы, но свидетельствует об обращении из объекта зависимого класса к атрибутам, методам или непосредственно к объектам независимого класса. Данное отношение в Case-средстве может автоматически отображаться на диаграмме при обратном проектировании или при синхронизации диаграммы и текста программы.
На рис. 14.8 показан условный пример, свидетельствующий о наличии зависимости класса Class_B от класса Class_A. В строке «public obrabotka(Class_A object_A)» используется ссылка на объект класса Class_A. В строке «String name = object_A.name;» выполняется обращение к атрибуту объекта класса Class_A. В строке «int age = object_A.getAge();» выполняется обращение к методу объекта класса Class_A.

Рис.14.8. Интерпретация зависимости
При одновременном наличии между классами отношений ассоциации и зависимости на диаграмме отображается ассоциация как более сильная связь.
На диаграммах разного типа, в том числе и на диаграмме классов, для показа специфики связей, поведения или взаимодействия могут отображаться объекты. Вид объекта аналогичен классу, но при этом его имя должно быть подчеркнуто и, как правило, приведены атрибуты и их значения, вызвавшие необходимость отображения объекта на диаграмме (рис. 14.9).

: ConnectDB

tipUser = «Администратор»
isConnect = true
nameDB = «Iskra»

Рис. 14.9. Пример объекта 
14.3. Правила и рекомендации по разработке диаграммы классов
При разработке диаграммы следует придерживаться следующих правил и рекомендаций [23–26].
1. За основу диаграммы классов при ее разработке берется диаграмма классов анализа.
2. Для классов должны быть определены и специфицированы все атрибуты и методы. Их спецификация, как правило, выполняется с учетом выбранного языка программирования.
3. При определении методов рекомендуется использовать сообщения с ранее разработанных диаграмм кооперации и последовательности.
4. Детальное проектирование граничных классов, как правило, не требуется. Большинство современных средств разработки поддерживает визуальную разработку интерфейса системы – меню, диалоговых форм, элементов диалоговых окон, панелей инструментов и т. д. В качестве исходных данных для их проектирования служат прототипы пользовательских интерфейсов. В связи с этим при проектировании таких классов основное внимание следует уделять особенностям отображения информации и специфичным операциям, которые возникают при диалоге пользователя с системой. Граничные классы, определяющие интерфейс взаимодействия с другими системами, требуют детального проектирования.
5. Для проектирования классов-сущностей можно применять подходы, используемые при проектировании БД, особенно в том случае, если данные будут храниться в таблицах БД. Если представление данных в БД и классах отличается друг от друга и в качестве хранилища информации будет применяться реляционная база данных, то рекомендуется разработать отдельную диаграмму классов, описывающую состав и структуру БД. Современные Case-средства позволяют разрабатывать такие диаграммы и синхронизировать их с БД.
6. Несмотря на то, что каждому объекту при выполнении программы автоматически назначается уникальный идентификатор, рекомендуется для классов-сущностей явно определять атрибуты, хранящие значения первичного ключа.
7. В отличие от реляционных БД поощряется использование в классах многозначных атрибутов в виде массивов, множеств, списков и т. д.
8. Управляющие классы следует проектировать только в случаях крайней необходимости – управления сложным взаимодействием объектов, реализации сложной бизнес-логики и вычислений, контроля целостности объектов и т. п. В противном случае функциональность этого класса лучше распределить между соответствующими граничными классами и классами-сущностями.
9. Для атрибутов рекомендуется назначать видимость private (закрытый) или protected (защищенный). Если требуется чтение значения такого атрибута из объектов других классов, то следует предусмотреть для него get-метод, а если возможность установки нового значения – set-метод. Пример приведен на рис. 14.10.



User


- name : String



+ getName() : String
+ setName(newName : String)


Рис. 14.10. Пример спецификации закрытого атрибута и методов для работы с ним
10. Для методов видимость public (обще­доступный) следует устанавливать только в случае крайней необходимости.
11. Ввиду большого количества классов в системе рекомендуется диаграммы классов разрабатывать отдельно для каждого пакета. По умолчанию Case-средства поддерживают именно такой подход проектирования, хотя и допускают разработку диаграмм, на которых присутствуют классы из разных пакетов.
12. При проектировании диаграммы и отдельных классов рекомендуется пользоваться шаблонами проектирования.
14.4. Пример построения диаграммы классов
На рис. 14.11 показан фрагмент диаграммы классов, полученный в результате обратного проектирования с помощью Case-средства Borland Together Architect 2006 for Eclipse.

Рис. 14.11. Фрагмент диаграммы классов
Данная диаграмма отражает структуру классов и связи между ними для пакета ru.iskraPUT.window системы ИСКРА-ПУТЬ. В диаграмму также включен класс InternalWindowDB из пакета ru.library.window, на базе которого определена половина классов пакета ru.iskraPUT.window. В правом верхнем углу части классов показаны стандартные классы языка Java, на основе которых они определены путем наследования.
Класс PutFame представляет собой главное окно программы, из которого вызываются внутренние диалоговые окна (классы, имя которых начинается на «Window»). Объект данного класса содержит ссылки на объекты, представляющие соответствующие окна, в связи с чем между ними на диаграмме показаны ассоциации.
В Together Architect при выборе класса на диаграмме отображается заголовок каждой секции. Так, для класса WindowSetting показаны:
 Attributes (англ. – атрибуты) – секция атрибутов;
 Operations (англ. – операции) – секция операций;
 Properties (англ. – свойства) – секция свойств. Под свойствами понимаются атрибуты, для которых возможно чтение с помощью общедоступного (public) get-метода. Например, значение закрытого атрибута checkBoxVisibleWord можно считать с помощью открытого метода getCheckBoxVisibleWord();
 Classes (англ. – классы) – секция внутренних классов, т. е. классов, определенных внутри рассматриваемого.
Статичные атрибуты (static) на диаграмме подчеркнуты.
К сожалению, в Together Architect не предусмотрена поддержка семантики двунаправленных ассоциаций. Несмотря на этот недостаток, данное Case-средство обладает богатыми возможностями прямого и обратного проектирования, что ставит его, наравне с продуктами линейки IBM Rational, в лидеры средств проектирования и разработки объектно-ориентированных систем. 
14.5. Шаблоны проектирования
В процессе разработки диаграмм классов, кооперации и последовательности рекомендуется использовать шаблоны (англ. templates) проектирования. В литературе часто встречаются альтернативные названия шаблонов – образцы или паттерны (англ. patterns). Шаблоны – это эффективные решения, разработанные опытными профессионалами. Идея применения шаблонов принадлежит Кристоферу Александеру (1977). Наиболее популярные шаблоны сводят в единые каталоги. Наиболее известными из них являются каталоги GoF «банды Четырех» (Гамма Е., Хелм Р., Джонсон Р. и Влиссидес Дж.) и GRASP (General Responsibility Assignment Software Patterns, англ. – общие шаблоны распределения обязанностей в программного обеспеченияах). Case-средства, как правило, содержат в своем составе библиотеки шаблонов, что существенно облегчает процессы проектирования и кодирования программ.
Шаблон представляет собой именованную пару «проблема / решение», содержащую готовое обобщенное решение типичной проблемы [24, 31–34]. Таким образом, шаблон
 имеет имя (например, Наблюдатель);
 содержит описание проблемы;
 содержит решение проблемы, которое должно адаптироваться при применении шаблона в конкретной ситуации;
 может содержать советы по поводу его применения в различных (специфичных) ситуациях и описание последствий его применения.
Рассмотрим классический шаблон «Наблюдатель» (англ. observer) [33, 34]. На рис. 14.12 показана диаграмма классов и исходные тексты классов, автоматически генерируемые и включаемые в модель проектирования Borland Together Architect 2006 for Eclipse при выборе и включении в проект шаблона.

Рис. 14.12. Шаблон проектирования «Наблюдатель» и исходные тексты классов
Имя. Наблюдатель (Observer).
Проблема. При изменении состояния объекта (значений атрибутов) требуется автоматически извещать другие объекты о происшедшем событии. Например, у объекта-источника ConcreteSubject, хранящего табличные данные, есть несколько объектов-наблюдателей ConcreteObserver, представляющих собой экранные формы представления этих данных (таблица, ступенчатый график и круговая диаграмма). Следует отметить, что объекты-наблюдатели могут принадлежать разным классам. При изменении данных в объекте-источнике автоматически должен меняться вид экранных форм.
Решение. Класс, описывающий объект-источник, должен содержать атрибут observers, хранящий список объектов-наблюдателей и допускающий их добавление или удаление из списка.
В Java одним из типов данных, отвечающим перечисленным требованиям, является ArrayList (массив-список). В этом классе должны быть определены методы добавления attach() и удаления deach() наблюдателя, а также метод notifyObservers(), который в цикле выполняет запуск процедуры обновления наблюдателей за счет вызова метода update(). Шаблонная диаграмма последовательности при вызове метода notifyObservers() показана на рис. 14.13.

Рис. 14.13. Диаграмма последовательности при вызове метода notifyObservers()
В классах, описывающих объекты-наблюдатели, в методе update() должен быть записан конкретный программный код, определяющий реакцию наблюдателя на изменение объекта-источника.
В связи с тем, что и объекты-источники ConcreteSubject, и объекты-наблюдатели ConcreteObserver могут быть разных типов (классов), они связаны между собой не напрямую, а через класс Subject и интерфейс Observer.
На рис. 14.12 показан один из двух вариантов использования отношения реализации – между классом ConcreteObserver и интерфейсом Observer.


Достарыңызбен бөлісу:
1   ...   62   63   64   65   66   67   68   69   ...   102




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет