Лекция
Привет, Вы узнаете о том , что такое паттерны проектирования с примерами на uml диаграмме классов, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое паттерны проектирования с примерами на uml диаграмме классов, диаграмма классов, паттерны проектирования , настоятельно рекомендую прочитать все из категории Проектирование веб сайта или программного обеспечения.
Символ класса на диаграмме может выглядеть различным образом в зависимости от детализации диаграммы:
Вопросы детализации будут рассмотрены в следующих разделах, а сейчас надо обратить внимание, что символ класса содержит имя (Player), набор операций (move, get_gealth) и атрибутов (pos, state). Для элементов класса могут задаваться тип, кратность, видимость и т.д.:
Формат спецификации атрибута:
видимость имя : тип [кратность] = значение_по_умолчанию
Формат спецификации операции:
видимость имя(аргумент: тип) = тип_возвращаемого_значения
В зависимости от параметра видимости элемент может быть:
Виртуальная функция и имя абстрактного класса выделяются курсивом, а статическая функция — подчеркивается.
Условные обозначения отношения между классами
В игре есть различные виды элементов (стены, сундуки, персонажи). Все эти элементы являются наследниками абстрактного класса AbstractItem, при этом часть из них умеет двигаться (такие элементы должны быть унаследованы от MovingItem). Наследование (отношение «является») изображается с помощью сплошной линии с закрытой стрелки, направленной в сторону суперкласса — на диаграмме класс MovingItem унаследован от AbstractItem, класс Player — от MovingItem и т.д. Штриховая линия с закрытой стрелкой задает отношение реализации (закрытое наследование).
Другой вид отношений между классами — включение, в объектно-ориентированном программировании различают два вида этого отношения — композицию и агрегацию. Об этом говорит сайт https://intellect.icu . Напомню, что композиция — это разновидность включения, когда объекты неразрывно связаны друг с другом (время их жизни совпадает), в случае агрегации, время жизни различно (например, когда объект вложенного класса может быть заменен другим объектом во время выполнения программы).
Отношение композиции обозначается закрашенным ромбом, который рисуется со стороны включающего класса — так, класс MovingItem включает в себя класс Position, т.к. перемещающийся объект всегда имеет позицию. Отношение агрегации изображается незакрашенным ромбом — игрок (Player) агрегирует состояние (IPlayerState).
Если вы знакомы с паттернами State, Strategy или Delegation — секцию можно пропустить.
На приведенной выше диаграмме используется шаблон проектирования Состояние (State), являющийся разновидностью шаблона Делегирование (Delegation) и близкой к паттерну Стратегия (Strategy). Суть делегирования заключается в том, что для упрощения логики работы класса, часть его работы может быть передана (делегирована) вспомогательному классу. В свою очередь, паттерн State может быть добавлен, например, на этапе рефакторинга если в нескольких функциях класса встречается разлапистая проверка состояния объекта для выполнения тех или иных действий. В нашем случае персонаж может взаимодействовать с ежом, предположим, что если персонаж движется сидя и контактирует с ежом — у него должно уменьшится здоровье, а если стоя — увеличится счет (points). Кроме ежа могла быть еда, противники, патроны и т.д. Для демонстрации такого паттерна создан абстрактный класс IPlayerState и два наследника StayState и SeatState. В классе Player, при нажатии кнопки Ctrlсостояние могло бы меняться на SeatState, а при отпускании — на StayState. Таким образом, при выполнении state->process_hedgehog(this)наш игрок каким-то образом, определенным объектом state, проконтактирует с ежиком.
Шаблон проектирования Delegation (и все его разновидности) — хороший пример для демонстрации агрегации. В нашем случае состояние игрока может меняться за счет изменения объекта по указателю, т.е. время жизни объектов различается.
Наиболее общий вид отношений между классами — ассоциация, обозначается сплошной линией (иногда со стрелкой). Вообще, и композиция, и агрегация, и обобщение (наследование) — являются частными случаями ассоциации. В нашей диаграмме с помощью ассоциации показано, что класс IPlayerState изменяет stats (health и points) объекта Player. Ассоциация может иметь название связи, поясняющую суть отношения. В качестве названия связей композиции и агрегации часто используется имя соответствующей переменной. Кроме того, ассоциация может иметь кратность, она задается на концах линии:
Последний вид отношений, который мы рассмотрим — зависимость, изображается штриховой (прерывистой) линией. Если есть стрелка — то направлена от зависимого к независимому классу, если стрелки нет — то классы зависят друг от друга. Под зависимостью понимается зависимость от интерфейса, т.е. если интерфейс независимого класса изменится — то придется вносить изменения в зависимый класс. В нашей диаграмме SeatState и StayState зависят от класса Player, т.к. обращаются к его методам для изменения характеристик игрока. Для изображения отношения дружбы между классами используется отношение зависимости с подписью friend.
Очевидно, что не все виды отношений стоит отображать на диаграмме и одни отношения могут быть заменены другими. Так, я убрал бы из нашего примера отношения зависимости, однако при некоторых обстоятельствах (например при эскизировании на маркерной доске) они были бы вполне уместны. Расстановка кратности и имен связей тоже выполняется далеко не во всех случаях. Вообще, не стоит помещать на диаграмму лишнюю информацию. Главное — диаграмма должна быть наглядной.
Хранитель (memento)
Цепочка обязанностей (chain of responsibility)
Наблюдатель (observer)
Команда (command)
Состояние (state)
Интерпретатор (interpreter)
Стратегия (strategy)
Итератор (iterator)
Шаблонный метод (template method)
Посредник (mediator)
Посетитель (visitor)
Адаптер (adapter)
Прокси (proxy)
Мост (bridge)
Абстрактная фабрика (abstract factory)
Компоновщик (composite)
Строитель (builder)
Декоратор (decorator)
Фабричный метод (factory method)
Фасад (facade)
Прототип (prototype)
Приспособленец (flyweight)
Одиночка (singleton)
Мы рассмотрели основные обозначения, используемые на диаграммах классов — их должно быть достаточно в подавляющем большинстве случаев. По крайней мере, владея этим материалом вы легко сможете разобраться в диаграммах шаблонов проектирования и понять эскиз любого проекта. Однако, как правильно строить такие диаграммы? В каком порядке и с какой степенью детализации? — ответ зависит от целей построения диаграммы, поэтому приведенный материал будет разбит на подразделы в соответствии с целями моделирования.
Стоит отметить, что у Гради Буча советы по использованию UML даны в книге «Руководство пользователя» [Buch_Rambo], но в его «Объектно-ориементированном анализе» [Buch] можно найти хорошие примеры и критерии качества проекта. Леоненков [Leonenkov] и вовсе избегает этой темы, оставляя лишь ссылки на литературу, конкретные рекомендации я нашел у Лармана [Larman] и Розенберга [Rosenberg], часть материала основана на моем личном опыте. Фаулер рассматривает UML как средство эскизирования, поэтому у него свой (сильно отличающийся от Буча и Розенберга) взгляд на диаграмму классов [Fauler].
Словарь системы формируется параллельно с разработкой диаграммы прецедентов, т.е. технического задания. Выглядит это следующим образом — вы задаете заказчику вопросы типа «что еще может сделать пользователь?», «что произойдет (должна выдать система) если пользователь сделает нажмет на <эту> кнопку?», а ответы на них записываете в виде описания прецедентов. Однако, заказчик, давая ответы может называть одни и те же вещи разными именами — из личного опыта: говоря «клетка», «пересечение», «узел» и «ячейка» заказчик может иметь ввиду одно и тоже. В вашей же системе все эти понятия должны быть представлены одной абстракцией (классом/функцией/…). Для этого при общении с заказчиком стоит фиксировать терминологию в виде словаря системы — очень хорошо с этим справляется диаграмма классов.
Гради Буч для построения словаря системы предлагает выполнять в следующем порядке [BuchRambo]:
В качестве примера рассмотрим словарь системы для игры «Сапер». На приведенной ниже диаграмме показан вариант, который получился в результате обсуждения задачи у моего студента. Видно, что на диаграмме изображены сущности и их атрибуты, понятные для заказчика, эту диаграмму стоит иметь перед глазами при составлении прецедентов чтобы не называть «Клетку» — «Полем», вводя всех в заблуждение. При построении словаря системы следует избегать нанесения на диаграмму функций классов, т.к. настолько детализированное распределение обязанностей лучше выполнять после построения диаграмм взаимодействия.
В процессе проектирования словарь системы может дополняться, Розенберг очень хорошо демонстрирует это в своей книге описывая итеративный процесс проектирования ICONIX [Rosenberg]. Например, после рассмотрения нескольких прецедентов может оказаться, что несколько классов реализуют один и тот же функционал — для решения проблемы надо более четко прописать обязанности каждого класса, возможно, добавить новый класс и перенести часть этих обязанностей ему.
Ларман предлагает строить концептуальную модель системы [Larman] — это примерно то, что мы описали как словарь системы, но помимо терминов предметной области в ней фиксируются некоторые отношения, понятные заказчику. Например, заказчик понимает (и фиксирует в техническом задании), что <покупку> оформляет <продавец> — следовательно, между продавцом и покупкой существует отношение ассоциации "оформляет". Я рекомендую строить концептуальную модель, дорабатывая словарь системы, хотя Ларман рекомендует сначала добавлять ассоциации, а затем — атрибуты.
В любом объектно-ориентированном процессе проектирования диаграмма классов является результатом, т.к. является моделью, наиболее близкой к реализации (коду). Существуют инструменты, способные преобразовать диаграмму классов в код — такой процесс называется кодогенерацией и поддерживается множеством IDE и средств проектирования. Например, кодогенерацию выполняет Visual Paradigm (доступно в виде плагинов для множества IDE), новые версии Microsoft Visual Studio, такие средств UML-моделирования как StarUML, ArgoUML и др. Чтобы построить по диаграмме хороший код, она должна быть достаточно подробной. Именно о такой диаграмме идет речь в этом разделе.
До Ларману [Larman] до начала построения диаграммы классов уровня проектирования должны быть построены диаграммы взаимодействия и концептуальная модель системы. При этом порядок построения диаграммы следующий:
Отношения, добавляемые на диаграмму классов уровня проектирования отличаются от тех, что были в концептуальной модели тем, что они могут быть не очевидны для заказчика (эту диаграмму он вообще смотреть не должен — она разрабатывается для программистов). Если на этапе анализа технического задания мы могли выделить основные сущности, не задумываясь о том, как это будет реализовано, то теперь обязанности между нашими классами должны быть окончательно распределены.
Например, при анализе задания на игру «Сапер» мы выделили классы <Флажок> и <Мина>, но будут ли эти классы в окончательном проекте или останутся только в воображении? — решение можно принять только проанализировав диаграммы взаимодействия. Ведь возможен и такой код:
Поясню (для тех, кто не пишет на С++) — тут создается перечисление, которое задает тип ячейки. Ячейка может принимать одно из этих шести значений (пустая открытая, пустая закрытая, пустая закрытая с флажком и т.п.). В таком случае, ячейка никак не сможет сама реагировать на нажатия мыши и отвечать за свое отображение (например пустая открытаядолжна выводить число мин вокруг себя) — все эти обязанности, видимо, лягут на класс PlayingGround.
Пример выше утрированный и однозначно не является образцом хорошего проектирования — на класс PlayingGround возложено слишком много обязанностей, но могли ли мы учесть это при анализе технического задания? Сможем ли мы это сделать до разработки диаграмм взаимодействия для проекта любой сложности? — именно поэтому построение диаграммы классов является последним этапом проектирования.
Под эскизированием понимают моделирование некоторой (интересной нам в данный момент) части системы. Например, эскизирование может выполняться на маркерной доске когда в вашу компанию попадет новый сотрудник и вы будете помогать ему «влиться» в существующий проект. Очевидно, что если если дать человеку диаграмму классов уровня проектирования — разбираться он будет долго. Суть эскизирования в избирательности — вы выносите на диаграмму только те элементы, которые важны для пояснения того или иного механизма.
Сторонником применения UML для эскизирования является Фаулер [Fauler], который считает, что целостный процесс проектирования с использованием UML слишком сложен. Эскизирование применяется очень часто (не только при объяснении проекта на маркерной доске):
Каких-либо конкретных рекомендаций к эскизам диаграмм классов предложить невозможно, кроме того, обычно это достаточно простая задача. Важно понимать суть — избирательность представления элементов снижает сложность восприятия диаграммы.
Частным случаем диаграммы классов является диаграмма «сущность-связь» (E-R диаграмма), используемая для моделирования логической схемы базы данных. В отличии от классических E-R диаграмм, диаграмма классов позволяет моделировать поведение (триггеры и хранимые процедуры).
Обычно ситуация выглядит следующим образом — вы разработали систему, состояние которой нужно сохранять между запусками, например:
Хранимые между запусками данные должны каким-то образом загружаться по запросу пользователя, т.е. должны задаваться параметры соответствующих классов. Например, приложение должно получить из базы данных список треков (маршрутов) и отобразить его в виде списка в меню программы. При выборе элемента списка — запросить в БД параметры трека, создать объект трека и отобразить его на карте. В любом случае, данные с базы используются при инициализации объектов программы — это важно понимать.
Для моделирования схемы БД с помощью диаграммы классов нужно [Buch_Rambo]:
паттерны проектирования классов и объектов
Механизмы повторного использования
Анализ данных, представленных в статье про паттерны проектирования с примерами на uml диаграмме классов, подтверждает эффективность применения современных технологий для обеспечения инновационного развития и улучшения качества жизни в различных сферах. Надеюсь, что теперь ты понял что такое паттерны проектирования с примерами на uml диаграмме классов, диаграмма классов, паттерны проектирования и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Проектирование веб сайта или программного обеспечения
Ответы на вопросы для самопроверки пишите в комментариях, мы проверим, или же задавайте свой вопрос по данной теме.
Комментарии
Оставить комментарий
Проектирование веб сайта или программного обеспечения
Термины: Проектирование веб сайта или программного обеспечения