Лабораторные работы Case-средства СУ
.pdfСодержание отчета по лабораторной работе
По результатам выполнения лабораторной работы необходимо подготовить отчет,
вкотором должны содержаться:
код выполненной общей части задания лабораторной работы;
код выполненной индивидуальной части лабораторной работы.
Контрольные вопросы
1.Какие преимущества дает использование паттерна Наблюдатель?
2.Покажите на диаграмме классов, где используется механизм наследования.
3.Что такое интерфейс, чем он отличается от абстрактного класса?
4.Покажите на диаграмме классов, где используется механизм композиции? Какие преимущества по сравнению с наследованием он дает?
5.Покажите в коде программы место использования механизма композиции.
6.Что необходимо будет поменять в коде и на диаграмме классов в случае добавления еще одного Наблюдателя?
7.Обязательно ли наличие интерфейса Observers и можно ли обойтись без него? К
чему это приведет в случае расширения кода?
Список литературы
1.Гамма Э.и др. - Приемы объектно-ориентированного проектирования. Паттерны проектирования – 2010г.
2.Влиссидес Д. - Применение шаблонов проектирования. Дополнительные штрихи –
2003г.
3.Ларман К. - Применение UML и шаблонов проектирования. – 2004г.
4.Фримен Эр., Фримен Эл., Сьерра К., Бейтс Б. - Паттерны проектирования – 2011г
31
Лабораторная работа №4. Использование паттерна Декоратор
Цель занятия: познакомится с принципом использования паттерна Декоратор при выборе архитектуры ПО и последующей реализации
Порядок выполнения работы:
1.Ознакомится с примером задания и разработанным кодом
2.Выполнить общую часть лабораторной работы
3.Выполнить индивидуальную часть лабораторной работы
Декоратор (англ. Decorator) — структурный шаблон проектирования,
предназначенный для динамического подключения дополнительного поведения к объекту.
Шаблон Декоратор предоставляет гибкую альтернативу практике создания подклассов с целью расширения функциональности.
Задача
Объект, который предполагается использовать, выполняет основные функции.
Однако может потребоваться добавить к нему некоторую дополнительную функциональность, которая будет выполняться до, после или даже вместо основной функциональности объекта.
Способ решения
Декоратор предусматривает расширение функциональности объекта без
определения подклассов.
Диаграмма классов
Участники
32
Класс ConcreteComponent — класс, в который с помощью шаблона Декоратор добавляется новая функциональность. В некоторых случаях базовая функциональность предоставляется классами, производными от класса ConcreteComponent. В подобных случаях класс ConcreteComponent является уже не конкретным, а абстрактным.
Абстрактный класс Component определяет интерфейс для использования всех этих классов.
Следствия
Добавляемая функциональность реализуется в небольших объектах. Преимущество состоит в возможности динамически добавлять эту функциональность до или после основной функциональности объекта ConcreteComponent.
Позволяет избегать перегрузки функциональными классами на верхних уровнях иерархии
Декоратор и его компоненты не являются идентичными
Реализация
Создается абстрактный класс, представляющий как исходный класс, так и новые,
добавляемые в класс функции. В классах-декораторах новые функции вызываются в требуемой последовательности — до или после вызова последующего объекта.
При желании остаётся возможность использовать исходный класс (без расширения функциональности), если на его объект сохранилась ссылка.
Замечания и комментарии
Хотя объект-декоратор может добавлять свою функциональность до или после функциональности основного объекта, цепочка создаваемых объектов всегда должна заканчиваться объектом класса ConcreteComponent.
И декоратор, и адаптер являются обертками вокруг объекта — хранят в себе ссылку на оборачиваемый объект и часто передают в него вызовы методов. Отличие декоратора от адаптера в том, что адаптер имеет внешний интерфейс, отличный от интерфейса оборачиваемого объекта, и используется именно для стыковки разных интерфейсов. Декоратор же имеет точно такой же интерфейс, и используется для добавления функциональности.
Для расширения функциональности класса возможно использовать как декораторы,
так и стратегии. Декораторы оборачивают объект снаружи, стратегии же вставляются в него внутрь по неким интерфейсам. Недостаток стратегии: класс должен быть спроектирован с возможностью вставления стратегий, декоратор же не требует такой
поддержки. Недостаток декоратора: он оборачивает ровно тот же интерфейс, что
33
предназначен для внешнего мира, что вызывает смешение публичного интерфейса и интерфейса кастомизации, которое не всегда желательно.
Общая часть лабораторной работы
В лекционном курсе была рассмотрена диаграмма классов, приведенная ниже.
Теоретические обоснования и идеи заложенные в основу этой диаграммы также были рассмотрены. Задача: по имеющейся диаграмме классов написать программный код,
используя паттерн Декоратор.
Описание задачи: Необходимо рассчитывать стоимость различных видов кофе с различными дополнениями и украшениями.
1. Создаем новый пустой проект в Visual Studio и выбираем соответствующие настройки:
34
2. Начинаем реализацию нашего проекта с интерфейса Beverage (Напиток), от которого буем наследовать все остальные классы и интерфейсы. Методы getDesciption() (описание напитка со всеми компонентами и дополнениями) и cost() (вычисляет стоимость напитка со всеми компонентами и дополнениями) являются чистыми виртуальными, таким образом их реализация будет содержаться в других классах. Это сделано для реализации динамического полиморфизма.
Заголовочный файл:
#pragma once class Beverage { public:
public: Beverage(void); ~Beverage(void);
virtual void getDescription()=0; virtual float cost()=0;
};
3. Реализуем классы конкретных напитков, например класс Espresso. В классе Espresso
реализованы методы Cost() и getDescription(), таким образом мы можем получить базовую стоимость напитка и его название.
Заголовочный файл:
35
#pragma once
#include "beverage.h" class Espresso :
public Beverage
{
public: Espresso(); ~Espresso(void); float cost();
void getDescription();
};
Файл реализации:
#include <iostream> using namespace std;
#include "Espresso.h"
Espresso::Espresso()
{
}
Espresso::~Espresso(void)
{
}
float Espresso::cost()
{
return 100;
}
void Espresso::getDescription()
{
cout << " Espresso" <<endl ;
}
По аналогии реализуются все остальные классы базовых напитков.
4. Реализуем интерфейс Decorator. Обратите внимание на двойную связь интерфейса
Decorator с интерфейсом Beverage. От интерфейса Decorator затем будем наследовать все возможные дополнения к нашему кофе. Интерфейс позволяет получить описание дополнений.
Реализация интерфейса Decorator:
#pragma once
#include "beverage.h" class CondimentDecorator :
public Beverage
{
public:
virtual void getDescription()=0;
};
5. Реализуем дополнение к базовому напитку, например класс Milk. В классе дополнения мы получаем название напитка и название дополнения, а также расчет общей стоимости
базового напитка и дополнения.
36
Заголовочный файл:
#pragma once
#include "condimentdecorator.h" class Milk :
public CondimentDecorator
{
Beverage *beverage;
public:
Milk (Beverage *beverage); ~Milk(void);
float cost();
void getDescription();
};
Файл реализации:
#include <iostream> using namespace std; #include "Milk.h"
Milk::Milk (Beverage *beverage)
{
this->beverage=beverage;
}
Milk::~Milk(void)
{
}
float Milk::cost()
{
return (20 + beverage->cost());
}
void Milk::getDescription()
{
beverage->getDescription(); cout << " Milk" <<endl ;
}
6. Реализуем функцию main(). Подключаем все необходимые классы и интерфейсы.
#include <iostream> #include <conio.h> #include "Beverage.h"
#include "CondimentDecorator.h" #include "Espresso.h"
#include "HouseBlend.h" #include "Milk.h"
using namespace std;
void main (void)
{
Beverage *beverage = new Espresso(); beverage = new Milk (beverage);
beverage = new Milk (beverage); beverage->getDescription();
cout << " rub " << beverage->cost()<<endl; getch();
}
37
В начале программы выбираем напиток и дополнения к этому напитку. Как результат получаем название выбранного напитка со всеми дополнениями и стоимость напитка со всеми дополнениями.
Индивидуальные задания
Вариант 1
Рассчитать стоимость автомобилей разных марок с учетом их комплектации.
Вариант 2
Рассчитать стоимость отправки посылки между 2 городами, учитывая такие параметры как класс отправления, объявленная ценность, страховка посылки.
Вариант 3
Рассчитать стоимость путешествия в несколько различных стран и городов,
учитывая такие параметры как: способ передвижения (автобус, самолет, поезд),
количество дней пребывания (7, 14, 20), класс гостиничного номера, вид из номера,
дополнительные экскурсии.
Содержание отчета по лабораторной работе
По результатам выполнения лабораторной работы необходимо подготовить отчет,
вкотором должны содержаться:
код выполненной общей части задания лабораторной работы;
код выполненной индивидуальной части лабораторной работы.
Контрольные вопросы
1.Какие преимущества дает использование паттерна Декоратор?
2.Покажите на диаграмме классов, где используется механизм наследования.
3.Что такое интерфейс, чем он отличается от абстрактного класса?
4.Покажите на диаграмме классов, где используется механизм композиции? Какие преимущества по сравнению с наследованием он дает?
5.Покажите в коде программы место использования механизма композиции.
38
6.Что необходимо будет поменять в коде и на диаграмме классов в случае добавления еще одного класса дополнений, например возможность добавления различных видов сиропа к кофе?
7.Что означает «двойная связь» между интерфейсами Beverage и Decorator?
8.Предложите способы для оптимизации программы, с учетом возможности создания классов дополнений.
Список литературы
1.Гамма Э.и др. - Приемы объектно-ориентированного проектирования. Паттерны проектирования – 2010г.
2.Влиссидес Д. - Применение шаблонов проектирования. Дополнительные штрихи –
2003г.
3.Ларман К. - Применение UML и шаблонов проектирования. – 2004г.
4.Фримен Эр., Фримен Эл., Сьерра К., Бейтс Б. - Паттерны проектирования – 2011г
39
