Лабораторная работа №25. Понятие графа. Алгоритмы поиска кратчайших путей


Пример создания UML-диаграмм архитектуры проекта с помощью PlantUML


Download 1.45 Mb.
bet36/39
Sana13.09.2023
Hajmi1.45 Mb.
#1677325
TuriЛабораторная работа
1   ...   31   32   33   34   35   36   37   38   39
Bog'liq
Blok 5

Пример создания UML-диаграмм архитектуры проекта с помощью PlantUML
Задание:​ разработать эскиз проекта системы управления книгами в библиотеке.
При выполнении задания ограничимся диаграммами классов и последовательности.
Создадим новый проект. В меню необходимо выбрать File>New Project. В диалоге выбора шаблона проекта, не нужно выбирать никакого шаблона (т.е. проект будет пустой, но с одним одноименным модулем). Название проекта ­ UMLLab. Если появится запрос на замену текущего проекта создаваемым, то лучше разрешить замену, так как старый проект уже не нужен.

После открытия проекта разверните содержимое модуля UMLLab с помощью серого треугольника. Папка .idea и файл UMLLab.iml хранят в себе все настройки проекта и модуля. Папка src будет включать в себя исходные коды .java программы.

Создание диаграммы классов
Откройте контекстное меню модуля и выберите создание новой UML­диаграммы классов.

В качестве имени файла можно ввести LibraryClassDiagram. В итоге среда разработки примет следующий вид.

В центре показан “код” диаграммы, которая загружается в качестве примера каждый раз при создании новой диаграммы классов. Слева показана уже нарисованная диаграмма. При редактировании кода диаграмма сразу же изменяется.
Код диаграммы начинается строчкой @startuml​ ​ и заканчивается @enduml​ ​. Между ними описываются сущности (классы, интерфейсы, перечисления и т. д.), а также связи между сущностями. Как
именно это делать, будет пояснено ниже, но полную информацию можно посмотреть в файле
PlantUML_Language_Reference_Guide​ или по адресу http://plantuml.sourceforge.net/classes.html.​
Удалим все, что находится между конечной и начальной строкой и приступим к проектированию системы управления книгами в библиотеке.
Так как составляется диаграмма классов​ ​, то главными сущностями будут именно классы, и диаграмма будет описывать большей частью структуру​ ​ системы. В будущей системе будут классы Book и Library. Создадим их.
@startuml
class Book {
}
class Library {
}
@enduml

Видно, что ни атрибутов, ни операций у этих двух классов пока нет. Добавим их исходя из необходимой функциональности.
У класса Book должны быть атрибуты: международный стандартный книжный номер (ISBN), название, автор, номер книги в библиотеке, год издания, а также операции, устанавливающие и получающие данные атрибуты. Однако по причине их многочисленности и общеупотребительности, эти операции не будут включаться в диаграмму классов. Помимо них, у класса Book нет других операций.
В классе Library должны быть атрибуты: количество книг и название библиотеки. Операции: найти нужную книгу по какому­либо параметру, например, по ISBN, добавить новую книгу в библиотеку, удалить необходимую книгу. @startuml skinparam classAttributeIconSize 0 class Book { ­ISBN : String
­author : String [1..*] ­numberInLibrary : long
­year : int
}
class Library {
­numberOfBooks : long
­name : String
+findBookByISBN(ISBN : String) : Book
+addNewBook(book : Book) : boolean
+deleteBook(number : long) : boolean
}
@enduml

Строка “skinparam classAttributeIconSize 0” отключает изображение метки видимости в виде картинки. Это нужно потому, что символы меток видимости стандартизированы, а картинки ­ нет, поэтому лучше использовать символы, если нет соглашений об иных обозначениях меток видимости.
Можно задать вопрос, а где же указано то, что в библиотеке хранятся книги? Пока на диаграмме изображены два разрозненных класса. Добавим эту информацию. Это можно сделать двумя путями, добавить некий атрибут в класс Library, который будет представлять собой список книг, хранящихся в библиотеке, а можно эту же самую информацию представить в виде ассоциации, но не однонаправленной, а двунаправленной.
Представление такой информации в виде ассоциации нагляднее, поэтому лучше выбрать именно ассоциацию. Почему ассоциация двусторонняя? Потому что не только библиотеке нужно хранить в себе информацию о всех книгах, входящих в неё, но и книга должна знать, какой библиотеке она принадлежит. Добавим информацию об этой ассоциации, дописав следующую строчку.
Book "0..*" <­­> "1" Library

На диаграмме сразу отобразились все изменения, классы были перекомпонованы. Данная ассоциация может быть прочитана как “в библиотеке может быть от нуля до бесконечности книг, а у книги может быть только одна библиотека (в которой она находится)”.
Продолжим конкретизировать эскиз. В библиотеке могут находиться также не только обычные книги, но и, к примеру, журналы. Самым очевидным решением было бы сделать класс Magazine подклассом класса Book. Но у журналов нет ISBN и конкретного автора! К тому же для большинства журналов для обозначения даты издания только года недостаточно. Соответственно, архитектурным решением может быть сделать общий абстрактный класс AbstractBook, в котором будут реализованы общие операции для всех сущностей, что находятся в библиотеке. От него будут наследоваться классы Book и Magazine. Но нельзя создать никаких экземпляров класса AbstractBook, а нам необходимо именно ими управлять в классе Library. Это решение не подходит, либо должно быть усовершенствовано.
Далее, для того, чтобы сделать возможным управление классами­наследниками AbstractBook, можно вынести методы из AbstractBook в интерфейс LibraryEntity. Абстрактный класс будет реализовывать этот интерфейс. Таким образом, Library сможет управлять объектами типа LibraryEntity. Например, станет возможным такой код.
LibraryEntity entity = new Book();
Почему такое возможно? Потому что абстрактный класс AbstractBook реализует интерфейс LibraryEntity, а класс Book наследует абстрактный класс AbstractBook. Язык Java позволяет присваивать интерфейсу ссылки на объекты тех классов, которые реализуют этот интерфейс.
Это решение и является подходящим для такой ситуации.
Соответственно, будут изменения и в классе Library, изменятся названия атрибутов, добавятся новые операции и изменятся старые. Дополнительно изменено имя свойства “numberInLibrary” на “ID”.
Если бы не было этапа проектирования, который сейчас и выполняется, то именно сейчас пришлось бы переписывать огромное количество кода. Именно поэтому принцип “сначала спроектируй ­ потом пиши код” позволяет повысить эффективность. Сейчас изменить архитектуру, даже полностью её переписать, будет намного легче, чем переписать весь код, который её в будущем будет реализовывать. Внесем все эти изменения в UML­код.
@startuml
skinparam classAttributeIconSize 0
interface LibraryEntity { +getID() : long
+getName() : String
}
abstract class AbstractBook {
­ID : long
­name : String
}
class Book { ­ISBN : String
­author : String [1..*]
­year : int
}
class Magazine {
­datePublication: LocalDate
­publisher : String
}
class Library {
­numberOfEntities : long
­name : String
+findEntityByName(name : String) : LibraryEntity
+findEntityByID(id : long) : LibraryEntity
+addNewEntity(entity : LibraryEntity) : boolean
+deleteEntity(id : long) : boolean
}
LibraryEntity "0..*" <­­> "1" Library
LibraryEntity <|.. AbstractBook
AbstractBook <|­­ Book
AbstractBook <|­­ Magazine
@enduml

Добавим комментарий к классу Magazine. class Magazine {
­datePublication: LocalDate
­publisher : String
}
note right: LocalDate is from DateTime API in Java 8

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

Download 1.45 Mb.

Do'stlaringiz bilan baham:
1   ...   31   32   33   34   35   36   37   38   39




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling