Файл: уфимский университет науки и технологий факультет математики и информационных технологий кафедра программирования и экономической информатики.docx
Добавлен: 10.11.2023
Просмотров: 174
Скачиваний: 8
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ
ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ОБРАЗОВАНИЯ
«УФИМСКИЙ УНИВЕРСИТЕТ НАУКИ И ТЕХНОЛОГИЙ»
ФАКУЛЬТЕТ МАТЕМАТИКИ И ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ
КАФЕДРА ПРОГРАММИРОВАНИЯ И ЭКОНОМИЧЕСКОЙ ИНФОРМАТИКИ
02.03.03 «Математическое обеспечение и администрирование информационных систем»
«Системное и интернет-программирование»
Информатика и программирование
Курсовая работа
Шаблоны проектирования.
Структурные паттерны- Паттерн «Декоратор»
(Decorator)
Научный руководитель
(ученая степень, звание, должность) Выполнил: студент 2 курса
к.ф.-м.н. наук, очной формы обучения группы 27
Доцент Иванов Ю.С.
Трунов К.В. (Фамилия И.О.)
(Фамилия И.О.)
УФА – 2023
Содержание
Cтроитель (Builder) -это паттерн проектирования, который используется для создания сложных объектов шаг за шагом. Он позволяет создавать различные варианты объектов, используя один и тот же процесс конструирования. 22
Плюсы 22
Упрощение создания сложных объектов: Паттерн Строитель позволяет разделить процесс создания сложного объекта на отдельные шаги. Это упрощает конструирование объекта и делает его более читаемым и поддерживаемым. 22
Гибкость и расширяемость: Строитель позволяет создавать различные варианты объектов, в зависимости от требований. Вы можете использовать разные строители для создания объектов с различными свойствами или конфигурациями. 22
Отделение процесса конструирования от самого объекта: Паттерн Строитель отделяет процесс создания объекта от самого объекта, что позволяет изменять процесс конструирования без изменения самого объекта. Это упрощает поддержку и повторное использование кода. 22
Поддержка неизменяемости объектов: При использовании паттерна Строитель вы можете создавать неизменяемые объекты, то есть объекты, у которых значения свойств устанавливаются только один раз во время создания. Это помогает обеспечить безопасность и надежность объектов. 22
Поддержка пошаговой отладки: При использовании паттерна Строитель вы можете пошагово отслеживать процесс создания объекта и проверять промежуточные результаты. Это полезно при отладке и обнаружении ошибок в процессе конструирования объекта. 22
Минусы 23
Минусы прототипа: 25
Неправильное использование может привести к ухудшению производительности: Если клонирование объектов является сложной и затратной операцией, неправильное использование прототипа может привести к ухудшению производительности программы. В таких случаях более подходящим может быть использование других паттернов или подходов к созданию объектов. 25
Необходимость поддержки клонирования объектов: Чтобы использовать прототип, объекты должны поддерживать операцию клонирования. Это означает, что классы должны реализовывать интерфейс Cloneable или иметь свой механизм клонирования. Это может быть затруднительно, если классы не предусмотрены для клонирования. 25
Плюсы 26
Минусы 26
Введение
Объектно-ориентированное программирование с использованием шаблонов проектирования призвано облегчить работу проектировщиков и разработчиков программного обеспечения. Но изучение и успешное использование этих методов может оказаться достаточно сложным делом.
Шаблоны проектирования — это руководства по решению повторяющихся проблем. Это не классы, пакеты или библиотеки, которые можно было бы подключить к вашему приложению и сидеть в ожидании чуда. Они скорее являются методиками решения определенных проблем в определенных ситуациях.
Шаблон проектирования, или паттерн, в разработке программного обеспечения — повторяемая архитектурная конструкция, представляющая собой решение проблемы проектирования, в рамках некоторого часто возникающего контекста.
Типы шаблонов: структурные, порождающие и поведенческие.
Структурные шаблоны проектирования имеют дело со способами представления объектов (такими, как деревья или связные списки). Они удобны во многих случаях, поскольку позволяют пользоваться множеством объектов как единым целым. порождающие шаблон проектирования связаны со способами создания сложных объектов, таких как лабиринты и деревья. порождающие шаблоны проектирования позволяют разнообразить создание объектов и управлять им, в том числе координировать группы объектов, создаваемые в ходе работы приложения. Без порождающие шаблонов проектирования пришлось бы писать отдельный программный код для каждого типа объектов или группы объектов, которые могут понадобиться в ходе работы приложения. порождающие образцы проектирования обычно создают объекты при помощи отдельного объекта или метода без прямого использования конструкторов. Поведенческий шаблон проектирования позволяет нам следить за поведением объектов.
Шаблоны проектирования могут быть применены на уровне архитектуры и (или) на уровне детального проектирования.
Применение каждого шаблона проектирования зависит от клиента – кода, который нуждается в сервисе, предоставляемом образцом проектирования. Клиент ссылается на точку входа шаблона проектирования (обычно это метод класса внутри образца). Кроме того, обычно подразумевается и третий тип кода, который можно назвать установочным кодом. Он устанавливает состояние шаблона проектирования. Установочный код не предназначен для повторного использования и предоставляет клиентам возможность легко взаимодействовать с шаблона проектирования. В частности, для работы с шаблоном проектирования клиенту следует знать как можно меньше о его структуре и внутренней работе.
-
Структурные шаблоны
Простыми словами: Структурные шаблоны в основном связаны с композицией объектов, другими словами, с тем, как сущности могут использовать друг друга. Ещё одним объяснением было бы то, что они помогают ответить на вопрос «Как создать программный компонент?».
Википедия гласит:
Структурные шаблоны — шаблоны проектирования, в которых рассматривается вопрос о том, как из классов и объектов образуются более крупные структуры.
-
Декоратор (Decorator)
Декоратор — структурный шаблон проектирования, предназначенный для динамического подключения дополнительного поведения к объекту. Шаблон декоратор предоставляет гибкую альтернативу практике создания подклассов с целью расширения функциональности.
Простыми словами: Шаблон декоратор позволяет вам динамически изменять поведение объекта во время работы, оборачивая их в объект класса декоратора.
Когда следует использовать декораторы?
Когда надо динамически добавлять к объекту новые функциональные возможности. При этом данные возможности могут быть сняты с объекта
Когда применение наследования неприемлемо. Например, если нам надо определить множество различных функциональностей и для каждой функциональности наследовать отдельный класс, то структура классов может очень сильно разрастись. Еще больше она может разрастись, если нам необходимо создать классы, реализующие все возможные сочетания добавляемых функциональностей.
Схематически шаблон "Декоратор" можно выразить следующим образом:
Формальная организация паттерна в C# могла бы выглядеть следующим образом:
abstract class Component
{
public abstract void Operation();
}
class ConcreteComponent : Component
{
public override void Operation()
{}
}
abstract class Decorator : Component
{
protected Component component;
public void SetComponent(Component component)
{
this.component = component;
}
public override void Operation()
{
if (component != null)
component.Operation();
}
}
class ConcreteDecoratorA : Decorator
{
public override void Operation()
{
base.Operation();
}
}
class ConcreteDecoratorB : Decorator
{
public override void Operation()
{
base.Operation();
}
}
Участники
-
Component: абстрактный класс, который определяет интерфейс для наследуемых объектов
-
ConcreteComponent: конкретная реализация компонента, в которую с помощью декоратора добавляется новая функциональность
-
Decorator: собственно декоратор, реализуется в виде абстрактного класса и имеет тот же базовый класс, что и декорируемые объекты. Поэтому базовый класс Component должен быть по возможности легким и определять только базовый интерфейс.
Класс декоратора также хранит ссылку на декорируемый объект в виде объекта базового класса Component и реализует связь с базовым классом как через наследование, так и через отношение агрегации.
-
Классы ConcreteDecoratorA и ConcreteDecoratorB представляют дополнительные функциональности, которыми должен быть расширен объект ConcreteComponent.
Рассмотрим пример. Допустим, купили мы квартиру, теперь надо купить в нее мебель. В квартире есть несколько комнат: кухня, спальня и т.д. И в зависимости от типа комнаты и какую мебель в нее хотите купить меняется цена. Теперь посмотрим, как это изобразить в программе на C#:
class Program
{
static void Main(string[] args)
{
Furniture furniture1 = new FurnitureKitchen();
furniture1 = new FurnitureTable(furniture1); // Мебель кухонная, стол
Console.WriteLine("Название: {0}", furniture1.Name);
Console.WriteLine("Цена: {0}", furniture1.GetCost());
Furniture furniture2 = new FurnitureKitchen();
furniture2 = new FurnitureСhair(furniture2);// Мебель кухоная, стул
Console.WriteLine("Название: {0}", furniture2.Name);
Console.WriteLine("Цена: {0}", furniture2.GetCost());
Furniture furniture3 = new FurnitureBedroom();
furniture3 = new FurnitureTable(furniture3);
furniture3 = new FurnitureСhair(furniture3);// Мебель в спальню, стол, стул
Console.WriteLine("Название: {0}", furniture3.Name);
Console.WriteLine("Цена: {0}", furniture3.GetCost());
Console.ReadLine();
}
}
// Furniture: абстрактный класс, который определяет интерфейс для наследуемых объектов
abstract class Furniture
{
public Furniture(string n)
{
this.Name = n;
}
public string Name { get; protected set; }
public abstract int GetCost();
}
//Мебель кухонная
class FurnitureKitchen : Furniture
{
public FurnitureKitchen() : base("Мебель кухонная")
{ }
public override int GetCost()
{
return 10;
}
}
//Мебель в спальню
class FurnitureBedroom : Furniture
{
public FurnitureBedroom()
: base("Мебель в спальню")
{ }
public override int GetCost()
{
return 8;
}
}
abstract class FurnitureDecorator : Furniture
{
protected Furniture furniture;
public FurnitureDecorator(string n, Furniture furniture) : base(n)
{
this.furniture = furniture;
}
}
class FurnitureTable : FurnitureDecorator
{
public FurnitureTable(Furniture p)
: base(p.Name + ", стол", p)
{ }
public override int GetCost()
{
return furniture.GetCost() + 3;
}
}
class FurnitureСhair : FurnitureDecorator
{
public FurnitureСhair(Furniture p)
: base(p.Name + ", стул", p)
{ }
public override int GetCost()
{
return furniture.GetCost() + 5;
}
}
В качестве компонента здесь выступает абстрактный класс Furniture, который определяет базовую функциональность в виде свойства Name и метода GetCost(). Эта функциональность реализуется двумя подклассами FurnitureKitchen и FurnitureBedroom, в которых жестко закодированы название мебели и цена.
Декоратором является абстрактный класс FurnitureDecorator, который унаследован от класса Furniture и содержит ссылку на декорируемый объект Furniture. В отличие от формальной схемы здесь установка декорируемого объекта происходит не в методе SetComponent, а в конструкторе.
Отдельные функциональности - добавление в комнаты дополнительную мебель реализованы через классы FurnitureKitchen и FurnitureBedroom, которые обертывают объект Furniture и добавляют к его имени название добавки, а к цене - стоимость добавки, то есть переопределяя метод GetCost и изменяя значение свойства Name.
Благодаря этому при создании комнаты с доп. мебелью произойдет ее обертывание декоратором:
Furniture furniture3 = new FurnitureBedroom();
furniture3 = new FurnitureTable(furniture3);
furniture3 = new FurnitureСhair(furniture3);
Сначала объект FurnitureBedroom обертывается декоратором FurnitureTable, а затем FurnitureСhair. И таких обертываний мы можем сделать множество. Просто достаточно унаследовать от декоратора класс, который будет определять дополнительный функционал.
А если бы мы использовали наследование, то в данном случае только для двух комнат с двумя дополнительными видами мебели нам бы пришлось создать восемь различных классов, которые бы описывали все возможные комбинации. Поэтому декораторы являются более предпочтительным в данном случае методом.
-
Адаптер (Adapter)
Адаптер — структурный шаблон проектирования, предназначенный для организации использования функций объекта, недоступного для модификации, через специально созданный интерфейс.
Простыми словами: Шаблон позволяет обернуть несовместимые объекты в адаптер, чтобы сделать их совместимыми с другим классом.
Плюсы шаблона "Адаптер":
-
Позволяет интегрировать уже существующий код в новую систему без необходимости его изменения. Это особенно полезно, если вы используете сторонние библиотеки или компоненты, которые не соответствуют требуемому интерфейсу. -
Облегчает повторное использование кода, поскольку можно адаптировать существующие классы для работы в различных контекстах. -
Упрощает тестирование, поскольку можно создавать адаптеры, имитирующие различные условия, и проверять взаимодействие с объектами. -
Позволяет сократить зависимость между компонентами системы, поскольку адаптер скрывает детали взаимодействия между классами.