Хелпикс

Главная

Контакты

Случайная статья





Лабораторная работа № 6 Шаблоны проектирования



Лабораторная работа № 6 Шаблоны проектирования

 

Цель работы

Изучить способы применения шаблонов проектирования при разработке программного обеспечения.

 

Порядок выполнения работы

1. Ознакомиться со структурной диаграммой и кодом предлагаемого в приложении базового приложения.

2. Переработать структуру логическую модель базового приложения следующим образом: 

- добавить один класс печатного издания (газета, географическая карта, и т.п.);

- добавить один класс категории читателей (аспирант, инженер и т.п.);

- разработать и добавить конкретную стратегию закупки печатных изданий;

- разработать и добавить конкретную стратегию выдачи книги читателям с учетом новой категории читателей;

- изменить алгоритм создания печатных изданий в фабрике печатных изданий с учетом нового класса печатного издания.

 

Содержание отчета

1. Цель работы.

2. UML диаграмма классов.

5. Текст программы на языке C++ с четким указанием внесенных усовершенствований.

6. Копии выходных форм программы.

7. Выводы.

 

Контрольные вопросы

1. Общая характеристика порождающих шаблонов.

2. Общая характеристика структурных шаблонов.

3. Общая характеристика шаблонов поведения.

4. Шаблон «Одиночка».

5. Шаблон «Абстрактная фабрика».

6. Шаблон «Стратегия».

7. Шаблон «Декоратор».

8. Шаблон «Наблюдатель».

9. Шаблон «Компоновщик».

 

Базовое приложение

Данное приложение является развитием примера выполнения лабораторной работы № 5, в котором моделируются сущности, связанные с работой библиотеки.

Детальное рассмотрение предметной области показывает, что объекты класса Книга, могут иметь различные абстракции сущности и поведения, в зависимости от того, в какой момент времени книга используется. Рассмотрим жизненный цикл экземпляра книги. Сначала книга выпускается издательством. В общем случае она может быть приобретена различными организациями: поступить в библиотеку, в магазин и т.д. В данной работе нас интересует поступление книги в библиотеку. После приобретения библиотекой, с книгой связываются дополнительные абстракции сущности и поведения. У книги появляется инвентарный номер, с ней связывается читатель, который ее берет, длительность периода, на который она выдается и т.д. Это приводит к тому, что в приложении из объекта класса «Книга» должен быть сформирован объект класса «Библиотечная книга», с дополнительными свойствами, хотя при этом он остается объектом класса «Книга». Это типовая ситуация, в которой используется шаблон проектирования «Декоратор». Для того чтобы приблизить приложение к более реальному, в нем введен класс «Печатное издание» так, чтобы можно было использовать не только класс «Книга», но и другие классы предметной области, например, «Журнал». Таким образом, класс «Книга» – это один из подклассов, производных от класса «Печатное издание». Поэтому шаблон декоратор применяется не к классу «Книга», а к базовому классу «Печатное издание».

В реальной действительности приобретение книг библиотеками выполняется в соответствии с различными критериями. Библиотеки различной направленности (научные библиотеки, библиотеки художественной литературы и т.д.), а также библиотеки различного уровня и с разными финансовыми возможностями приобретают книги в соответствии с разными алгоритмами. Поэтому в данном приложении используется шаблон «Стратегия», который позволяет задавать объектам класса «Библиотека» разные алгоритмы покупки книги. Эти алгоритмы должны реализовывать общий интерфейс стратегии закупки.

Во многих библиотеках различаются условия выдачи книг различным категориям читателей. Например, в университетских библиотеках, как правило, преподавателям позволено брать книги на неопределенный срок, в то время как студенты должны сдавать книги либо каждый год, либо в конце обучения в университете. Таким образом, рассуждения приводят нас к тому, что для класса «Библиотека» должны быть реализованы различные стратегии выдачи книг с общим интерфейсом.

Для моделирования производства печатных изданий, в приложении используется шаблон проектирования «Абстрактная фабрика» в его упрощенном варианте: абстрактный класс фабрики совмещен с конкретным классом. Фабрика создает набор объектов классов печатных изданий (книги и журналы) для проведения моделирования всей предметной области.

В данном приложении нужен один генератор объектов печатных изданий. Поэтому фабрика печатных изданий реализована в соответствии с шаблоном проектирования «Одиночка». Таким образом, один тот же класс фабрики печатных изданий одновременно реализует два порождающих шаблона проектирования.

Головная функция приложения выполняет создание объектов классов предметной области. В ней создаются две объекта библиотек, каждый из которых содержит различные комбинации стратегии приобретения печатных изданий и стратегии их выдачи. Головная функция приложения составлена таким образом, чтобы выполнились все предусмотренные стратегии для разных классов печатных изданий и разных классов читателей.

В данном приложении используется информация времени исполнения о фактических классах объектов. Для того, чтобы можно было использовать для этой цели оператор dynamic_cast<> надо, чтобы в свойствах проекта был установлен соответствующий флаг для компиляции ().

 

Рисунок 1 Диаграмма классов для базового приложения

 

Рисунок 2 Классы конкретные стратегии

 

Рисунок 3 Установка флага Enable Run-Time Type Information (RTTI) в настройках проекта

 

Исходный код программы см. в приложении.

Выход программы показан на рисунке.

Рисунок 4 Результат выполнения базового приложения

 

Приложение

// Book.h: interface for the Book class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_BOOK_H__D4766295_CB7F_473E_AD58_2634A819122E__INCLUDED_)

#define AFX_BOOK_H__D4766295_CB7F_473E_AD58_2634A819122E__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "IItem.h"

 

class Book : public IItem

{

public:

Book(const string& title, double price, const string& author);

virtual ~Book();

 

// Реализация интерфейса печатного издания

string GetTitle() const

{

       return _title;

}

 

// Реализация интерфейса печатного издания

double GetPrice() const

{

       return _price;

}

 

// Добавленный метод, специфический для книги

string GetAuthor() const

{

       return _author;

}

 

private:

string _title;

double _price;

string _author;

 

};

 

#endif // !defined(AFX_BOOK_H__D4766295_CB7F_473E_AD58_2634A819122E__INCLUDED_)

// IDeliveryStrategy.h: interface for the IDeliveryStrategy class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_IDELIVERYSTRATEGY_H__E4A46F74_2FDF_4E05_B05B_A0ED226E11DE__INCLUDED_)

#define AFX_IDELIVERYSTRATEGY_H__E4A46F74_2FDF_4E05_B05B_A0ED226E11DE__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "Reader.h"

 

//

// Интерфейс стратегии определения времени владения книгой

//

class IDeliveryStrategy 

{

public:

 

// Вычислить период (в днях) владения книгой для заданного читателя

virtual int HoldPeriod(const Reader& reader) const = 0;

 

};

 

#endif // !defined(AFX_IDELIVERYSTRATEGY_H__E4A46F74_2FDF_4E05_B05B_A0ED226E11DE__INCLUDED_)

// IItem.h: interface for the IItem class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_IITEM_H__E4EFABA4_D391_42E1_8C3B_C1338A8B35DE__INCLUDED_)

#define AFX_IITEM_H__E4EFABA4_D391_42E1_8C3B_C1338A8B35DE__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include <string>

 

using namespace std;

 

//

// Печатное издание

//

class IItem 

{

public:

 

// Название

virtual string GetTitle() const = 0;

 

// Стоимость

virtual double GetPrice() const = 0;

 

};

 

#endif // !defined(AFX_IITEM_H__E4EFABA4_D391_42E1_8C3B_C1338A8B35DE__INCLUDED_)

// IPurchaseStrategy.h: interface for the IPurchaseStrategy class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_IPURCHASESTRATEGY_H__463F6A66_FAFD_4D75_AACB_7D898CCFD535__INCLUDED_)

#define AFX_IPURCHASESTRATEGY_H__463F6A66_FAFD_4D75_AACB_7D898CCFD535__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "IItem.h"

 

//

// Интерфейс для стратегии закупки печатного издания

//

class IPurchaseStrategy 

{

public:

 

// Возвращает true, если печатное издание подходит для закупки.

// Здесь передается ссылка на объект (передача объекта

// абстрактного класса по значению не может быть выполнена, т.к.

// требует конструирования объекта)

virtual bool IsAcceptable(const IItem& item) = 0;

 

};

 

#endif // !defined(AFX_IPURCHASESTRATEGY_H__463F6A66_FAFD_4D75_AACB_7D898CCFD535__INCLUDED_)

// ItemFactory.h: interface for the ItemFactory class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_ITEMFACTORY_H__E790A7FC_2B98_4187_972E_E33B95B5C143__INCLUDED_)

#define AFX_ITEMFACTORY_H__E790A7FC_2B98_4187_972E_E33B95B5C143__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "Book.h"

#include "Journal.h"

//

// Фабрика печатных изданий

//

class ItemFactory 

{

public:

// Фабричный метод для создания экземпляра книги.

// За уничтожение объекта отвечает клиент.

Journal* CreateJournal();

 

// Фабричный метод для создания экземпляра журнала.

// За уничтожение объекта отвечает клиент.

Book* CreateBook();

 

// Вернуть ссылку на экземпляр "одиночки", который и есть экземпляр фабрики.

static ItemFactory& Instance();

 

virtual ~ItemFactory();

 

private:

 

// Единственный экземпляр "одиночки" - статическое поле

static ItemFactory s_instance;

 

// Счетчик созданных "продуктов" - печатных изданий.

// Это поле объекта (не статическое поле). Оно предназначено для генерации

// искусственных экземпляров печатных изданий.

int _counter;

 

// Закрытый конструктор для того, чтобы клиенты класса не могли создавать

// экзепляры фабрики. Так реализуется шаблон проектирования "одиночка".

ItemFactory();

 

};

 

#endif // !defined(AFX_ITEMFACTORY_H__E790A7FC_2B98_4187_972E_E33B95B5C143__INCLUDED_)

// Journal.h: interface for the Journal class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_JOURNAL_H__9285DEEB_084E_4602_8FB0_765200D44FDF__INCLUDED_)

#define AFX_JOURNAL_H__9285DEEB_084E_4602_8FB0_765200D44FDF__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "IItem.h"

 

class Journal : public IItem

{

public:

Journal(const string& title, double price, const string& volume);

virtual ~Journal();

 

// Реализация интерфейса печатного издания

string GetTitle() const

{

       return _title;

}

 

// Реализация интерфейса печатного издания

double GetPrice() const

{

       return _price;

}

 

// Получть название тома (номера) журнала.

// Добавленный метод, специфический для журнала

string GetVolume() const

{

       return _volume;

}

 

private:

string _title;

double _price;

string _volume;

 

};

 

#endif // !defined(AFX_JOURNAL_H__9285DEEB_084E_4602_8FB0_765200D44FDF__INCLUDED_)

// Lecturer.h: interface for the Lecturer class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_LECTURER_H__206173A0_0656_43C2_ABE7_A1A87AE65AF0__INCLUDED_)

#define AFX_LECTURER_H__206173A0_0656_43C2_ABE7_A1A87AE65AF0__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "Reader.h"

 

class Lecturer : public Reader

{

public:

Lecturer(const string& name, const string& position);

virtual ~Lecturer();

 

string GetPosition()

{

       return _position;

}

 

private:

 

// Занимаемая должность

string _position;

};

 

#endif // !defined(AFX_LECTURER_H__206173A0_0656_43C2_ABE7_A1A87AE65AF0__INCLUDED_)

// Library.h: interface for the Library class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_LIBRARY_H__24F4459E_E564_44D8_B05D_8D49D29181BD__INCLUDED_)

#define AFX_LIBRARY_H__24F4459E_E564_44D8_B05D_8D49D29181BD__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "IPurchaseStrategy.h"

#include "IDeliveryStrategy.h"

#include "IItem.h"

#include "LibraryItem.h"

#include <vector>

#include <algorithm>

 

class Library 

{

public:

vector<LibraryItem*> GetLibItems();

vector<Reader*>& GetReaders();

 

// При создании экземпляра класса библиотека надо указать

// стратегии приобретения печатных изданий и вычисления

// периода владения единицей хранения читателями.

Library(

       const string& name,

       IPurchaseStrategy* purchaseStrategy,

       IDeliveryStrategy* deliveryStrategy);

 

// При уничтожении объекта, надо уничтожить и объекты

// стратегий, и единицы хранения

virtual ~Library();

 

// Название библиотеки

string GetName()

{

       return _name;

}

 

// Попытаться приобрести печатное издание.

// Если оно приобретено, то возвращается true,

// в противном случае - false

bool PurchaseItem(IItem* item);

 

// Зарегистрировать читателя

void AddReader(Reader* reader);

 

// Выдать книгу читателю

void LetLibItemOut(LibraryItem* item, Reader* reader);

 

// Вернуть книгу в библиотеку

void PutLibItemBack(LibraryItem* libItem);

 

private:

 

string _name;

// Стратегии

IPurchaseStrategy* _purchaseStrategy;

IDeliveryStrategy* _deliveryStrategy;

 

// Последний присвоенный инвентарный номер

int _lastInventoryNumber;

 

// Все единцы хранения

vector<LibraryItem*> _libItems;

 

// Все читатели

vector<Reader*> _readers;

};

 

#endif // !defined(AFX_LIBRARY_H__24F4459E_E564_44D8_B05D_8D49D29181BD__INCLUDED_)

// LibraryItem.h: interface for the LibraryItem class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_LIBRARYITEM_H__A4915813_7738_4B67_82F1_17BA66EA451F__INCLUDED_)

#define AFX_LIBRARYITEM_H__A4915813_7738_4B67_82F1_17BA66EA451F__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "IItem.h"

#include "Reader.h"

 

//

// Декоратор для единицы хранения.

// Добавляет структуру и поведение необходимые для использования

// классом библиотека: инвентарный номер, ссылку на читателя,

//

class LibraryItem : IItem

{

public:

IItem* GetItem();

 

int GetInventoryNumber() const

{

       return _inventoryNumber;

}

 

int GetHoldPeriod() const

{

       return _holdPeriod;

}

 

void SetHolderPeriod(int holdPeriod)

{

       _holdPeriod = holdPeriod;

}

 

// Вернет NULL, если книга - в библиотеке

Reader* GetReader()

{

       return _reader;

}

 

// Установить владельца единицы хранения. Если нужно указать,

// единица хранения находится в библиотеке, то надо установить

// значение NULL

void SetReader(Reader* reader)

{

       _reader = reader;

}

 

// При создании декоратора печатного издания, сразу же

// надо присвоить ему инвентарный номер.

LibraryItem(IItem* item, int inventoryNumber);

 

//

// При уничтожении декоратора надо уничтожить и "обернутый" объект

// иначе он будет создавать "мусор" в памяти

//

virtual ~LibraryItem();

 

string GetTitle() const

{

       return _item->GetTitle();

}

 

double GetPrice() const

{

       return _item->GetPrice();

}

 

private:

// Это указатель на "обернутый объект"

IItem* _item;

 

//

// Дополнительные (декорирующие) абстракции сущности, свойственные

// единице хранения в библиотеке

//

 

// Инвентарный номер

int _inventoryNumber;

 

// Время владения книгой читателем

int _holdPeriod;

 

// Адрес объекта класса читатель, который владеет книгой в конкретный момент.

// Если книга находится в библиотеке, то он должен быть NULL

Reader* _reader;

 

};

 

#endif // !defined(AFX_LIBRARYITEM_H__A4915813_7738_4B67_82F1_17BA66EA451F__INCLUDED_)

// PublicLibraryStrategy.h: interface for the PublicLibraryStrategy class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_PUBLICLIBRARYSTRATEGY_H__38B59517_9DDE_4CEA_AE86_42CC9272B22C__INCLUDED_)

#define AFX_PUBLICLIBRARYSTRATEGY_H__38B59517_9DDE_4CEA_AE86_42CC9272B22C__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "IDeliveryStrategy.h"

 

//

// Реализация стратегии определения времени владения книгой.

// В данном случае (публичная библиотека) период для

// всех категорий читателей одинаковый. Он задается при

// создании экземпляра стратегии

//

class PublicLibraryStrategy : public IDeliveryStrategy

{

public:

PublicLibraryStrategy(int nomianlHoldPeriod);

virtual ~PublicLibraryStrategy();

 

// Реализация метода интерфейса стратегии

int HoldPeriod(const Reader& reader) const;

 

private:

int _nomianlHoldPeriod;

 

};

 

#endif // !defined(AFX_PUBLICLIBRARYSTRATEGY_H__38B59517_9DDE_4CEA_AE86_42CC9272B22C__INCLUDED_)

// PurchaseCheapStrategy.h: interface for the PurchaseCheapStrategy class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_PURCHASECHEAPSTRATEGY_H__FC9FC695_FA47_4AD2_B23B_F5CF6DCD10A8__INCLUDED_)

#define AFX_PURCHASECHEAPSTRATEGY_H__FC9FC695_FA47_4AD2_B23B_F5CF6DCD10A8__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "IPurchaseStrategy.h"

 

//

// Реализация стратегии закупки печатного издания: закупать, если

// стоимость не превышает заданную.

//

class PurchaseCheapStrategy : public IPurchaseStrategy

{

public:

 

// Реализация абстрактного метода из родтельского интерфейса.

// Реализует проверку печатного издания на допустимую цену

bool IsAcceptable(const IItem& item);

 

PurchaseCheapStrategy(double maxPrice);

virtual ~PurchaseCheapStrategy();

 

private:

double _maxPrice;

 

};

 

#endif // !defined(AFX_PURCHASECHEAPSTRATEGY_H__FC9FC695_FA47_4AD2_B23B_F5CF6DCD10A8__INCLUDED_)

// PurchaseExpensiveStrategy.h: interface for the PurchaseExpensiveStrategy class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_PURCHASEEXPENSIVESTRATEGY_H__81F20822_8C43_46B9_8927_B998ACDA7F28__INCLUDED_)

#define AFX_PURCHASEEXPENSIVESTRATEGY_H__81F20822_8C43_46B9_8927_B998ACDA7F28__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "IPurchaseStrategy.h"

 

//

// Реализация стратегии закупки печатного издания: закупать, если

// стоимость книги не ниже заданной.

//

class PurchaseExpensiveStrategy : public IPurchaseStrategy

{

 

public:

bool IsAcceptable(const IItem &item);

PurchaseExpensiveStrategy(int minPrice);

virtual ~PurchaseExpensiveStrategy();

 

 

private:

double _minPrice;

 

};

 

#endif // !defined(AFX_PURCHASEEXPENSIVESTRATEGY_H__81F20822_8C43_46B9_8927_B998ACDA7F28__INCLUDED_)

// Reader.h: interface for the Reader class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_READER_H__ED9F6DCD_D659_48E3_BB22_931EAA24C39B__INCLUDED_)

#define AFX_READER_H__ED9F6DCD_D659_48E3_BB22_931EAA24C39B__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include <string>

 

using namespace std;

 

class Reader 

{

public:

string GetName();

 

virtual ~Reader();

 

protected:

 

// Защищенный конструктор не позволит создавать объекты данного класса,

// но будет использоваться в классах-потомках

Reader(const string& name);

 

private:

string _name;

 

};

 

#endif // !defined(AFX_READER_H__ED9F6DCD_D659_48E3_BB22_931EAA24C39B__INCLUDED_)

// stdafx.h : include file for standard system include files,

// or project specific include files that are used frequently, but

// are changed infrequently

//

 

#if !defined(AFX_STDAFX_H__A49E9922_489F_4609_9B39_8190D6F40BB1__INCLUDED_)

#define AFX_STDAFX_H__A49E9922_489F_4609_9B39_8190D6F40BB1__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#define WIN32_LEAN_AND_MEAN    // Exclude rarely-used stuff from Windows headers

 

#include <stdio.h>

 

// TODO: reference additional headers your program requires here

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_STDAFX_H__A49E9922_489F_4609_9B39_8190D6F40BB1__INCLUDED_)

// Student.h: interface for the Student class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_STUDENT_H__551614A6_17DA_44F9_894F_6C68CA5A9F35__INCLUDED_)

#define AFX_STUDENT_H__551614A6_17DA_44F9_894F_6C68CA5A9F35__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "Reader.h"

 

class Student : public Reader

{

public:

Student(const string& name, int clazz);

virtual ~Student();

     

int GetClass() const

{

       return _class;

}

 

private:

int _class;

 

};

 

#endif // !defined(AFX_STUDENT_H__551614A6_17DA_44F9_894F_6C68CA5A9F35__INCLUDED_)

// UniversityLibraryStrategy.h: interface for the UniversityLibraryStrategy class.

//

//////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_UNIVERSITYLIBRARYSTRATEGY_H__CDD8B903_6CC0_41EC_B154_E447EDBFAFEA__INCLUDED_)

#define AFX_UNIVERSITYLIBRARYSTRATEGY_H__CDD8B903_6CC0_41EC_B154_E447EDBFAFEA__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

 

#include "IDeliveryStrategy.h"

// Ðàçëè÷íûå êëàññû ÷èòàòåëåé íóæíû â ðåàëèçàöèè,

#include "Student.h"

#include "Lecturer.h"

 

 

//

// Ðåàëèçàöèÿ ñòðàòåãèè îïðåäåëåíèÿ âðåìåíè âëàäåíèÿ

// ïå÷àòíûì èçäàíèåì äëÿ óíèâåðñèòåòñêîé áèáëèîòåêè.

// Ïåðèîä âëàäåíèÿ äîëæåí áûòü ðàçëè÷íûì äëÿ ñòóäåíòîâ

// ìëàäøèõ êóðñîâ, ñòóäåíòîâ ñòàðøèõ êóðñîâ è ïðåïîäàâàòåëåé.

//

class UniversityLibraryStrategy : public IDeliveryStrategy

{

public:

UniversityLibraryStrategy(int averagePeriod);

virtual ~UniversityLibraryStrategy();

 

int HoldPeriod(const Reader& reader) const;

 

private:

int _averagePeriod;

 

};

 

#endif // !defined(AFX_UNIVERSITYLIBRARYSTRATEGY_H__CDD8B903_6CC0_41EC_B154_E447EDBFAFEA__INCLUDED_)

// Book.cpp: implementation of the Book class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Book.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

Book::Book(const string & title, double price, const string& author)

: _title(title), _price(price), _author(author)

{

}

 

Book::~Book()

{

 

}

// IDeliveryStrategy.cpp: implementation of the IDeliveryStrategy class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "IDeliveryStrategy.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

//DEL IDeliveryStrategy::IDeliveryStrategy()

//DEL {

//DEL

//DEL }

 

//DEL IDeliveryStrategy::~IDeliveryStrategy()

//DEL {

//DEL

//DEL }

// IItem.cpp: implementation of the IItem class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "IItem.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

//DEL IItem::IItem()

//DEL {

//DEL

//DEL }

 

//DEL IItem::~IItem()

//DEL {

//DEL

//DEL }

// IPurchaseStrategy.cpp: implementation of the IPurchaseStrategy class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "IPurchaseStrategy.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

//DEL IPurchaseStrategy::IPurchaseStrategy()

//DEL {

//DEL

//DEL }

 

//DEL IPurchaseStrategy::~IPurchaseStrategy()

//DEL {

//DEL

//DEL }

// ItemFactory.cpp: implementation of the ItemFactory class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "ItemFactory.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

// Инициализация статического поля класса,

// для него будет вызыван конструктор без параметров

ItemFactory ItemFactory::s_instance;

 

ItemFactory::ItemFactory() : _counter(0)

{

}

 

ItemFactory::~ItemFactory()

{

 

}

 

ItemFactory& ItemFactory::Instance()

{

return s_instance;

}

 

Book* ItemFactory::CreateBook()

{

_counter++;

 

// Преобразование числа в строку

char buffer[10];

_itoa(_counter, buffer, 10);

 

const string title = string("Краткое руководство по С++. Том ") + string(buffer);

const double price = _counter;

string author = string("Страуструп Б.");

 

return new Book(title, price, author);

}

 

Journal* ItemFactory::CreateJournal()

{

_counter++;

 

// Преобразование числа в строку

char buffer[5];

_itoa(_counter, buffer, 5);

 

string title = string("Мурзилка");

double price = _counter;

string volume = string(buffer);

 

return new Journal(title, price, volume);

 

}

// Journal.cpp: implementation of the Journal class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Journal.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

Journal::Journal(const string & title, double price, const string& volume)

: _title(title), _price(price), _volume(volume)

{

 

}

 

Journal::~Journal()

{

 

 

}

// Lecturer.cpp: implementation of the Lecturer class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Lecturer.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

Lecturer::Lecturer(const string& name, const string& position)

: Reader(name), _position(position)

{

 

}

 

Lecturer::~Lecturer()

{

 

}

// Library.cpp: implementation of the Library class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Library.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

Library::Library(

                    const string& name,

                    IPurchaseStrategy* purchaseStrategy,

                    IDeliveryStrategy* deliveryStrategy)

: _name(name),

_purchaseStrategy(purchaseStrategy),

_deliveryStrategy(deliveryStrategy),

_lastInventoryNumber(0)

{

 

}

 

Library::~Library()

{

if (_purchaseStrategy != NULL)

{

       delete _purchaseStrategy;

}

 

if (_deliveryStrategy != NULL)

{

       delete _deliveryStrategy;

}

 

for(int i = 0; i < _libItems.size(); i++)

{

       delete _libItems[i];

}

}

 

bool Library::PurchaseItem(IItem* item)

{

bool result;

// Проверить, возможно ли приобрести печатное издание

// в соответствии с политикой приобретения

if (_purchaseStrategy->IsAcceptable(*item))

{

       // Печатное издание приобретается, оно становится

       // единицей хранения. Поэтому создается экземпляр

       // декоратора. Назначается инвентарный номер

       _lastInventoryNumber++;

       LibraryItem* libItem = new LibraryItem(item, _lastInventoryNumber);

 

       _libItems.push_back(libItem);

}

else

{

       // Нельзя приобретать

       result = false;

}

return result;

}

 

void Library::AddReader(Reader* reader)

{

_readers.push_back(reader);

}

 

void Library::LetLibItemOut(LibraryItem* item, Reader* reader)

{

// Выдавать книгу можно только читателю, зарегистрированному

// в данной библиотеке

if (find(_readers.begin(), _readers.end(), reader) != _readers.end())

{

       // Кнмгу можно выдать, если она не была взята другим или этим читателем

       if (item->GetReader() == NULL)

       {

             // Получить величину периода владения книгой в соответствии с

             // со стратегией и выдать книгу

             int holdPeriod = _deliveryStrategy->HoldPeriod(*reader);

 

             item->SetHolderPeriod(holdPeriod);

       item->SetReader(reader);

       }

}

}

 

void Library::PutLibItemBack(LibraryItem* libItem)

{

libItem->SetReader(NULL);

}

 

vector<Reader*>& Library::GetReaders()

{

return _readers;

}

 

vector<LibraryItem*> Library::GetLibItems()

{

return _libItems;

}

// LibraryItem.cpp: implementation of the LibraryItem class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "LibraryItem.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

LibraryItem::LibraryItem(IItem* item, int inventoryNumber)

: _item(item),

_inventoryNumber(inventoryNumber),

_reader(NULL),

_holdPeriod(0)

 

 

{

 

}

 

LibraryItem::~LibraryItem()

{

 

}

 

 

IItem* LibraryItem::GetItem()

{

return _item;

}

// PatternsApplication.cpp : Defines the entry point for the console application.

//

 

#include "stdafx.h"

 

#include "Library.h"

#include "PurchaseCheapStrategy.h"

#include "PurchaseExpensiveStrategy.h"

#include "PublicLibraryStrategy.h"

#include "UniversityLibraryStrategy.h"

#include "Student.h"

#include "Lecturer.h"

#include "ItemFactory.h"

#include <windows.h>

#include "LibraryItem.h"

#include <iostream>

#include "Book.h"

#include "Journal.h"

 

 

using namespace std;

//

// Показать состояние библиотеки и книг в ней

//

void Show(Library& lib);

 

 

int main(int argc, char* argv[])

{

     

//

// Библиотеки с различными стратегиями

//

Library vlsuLibrary(

       string("Библиотека ВлГУ"),

       new PurchaseCheapStrategy(5),

       new UniversityLibraryStrategy(50));

Library regionLibrary(

       string("Областная библиотека"),

       new PurchaseExpensiveStrategy(4),

       new PublicLibraryStrategy(65));

 

//

// Читатели разлчиных категорий

//

Student st1(string("Петров"), 1);

Student st2(string("Иванов"), 4);

Student st3(string("Сидоров"), 5);

 

Lecturer lec1(string("Кутузов"), string("доцент"));

Lecturer lec2(string("Суворов"), string("ассистент"));

 

//

// Регистрируем читателей в библиотеках. Некоторые из читателей -

// в нескольких библиотеках

//

vlsuLibrary.AddReader(&st1);

vlsuLibrary.AddReader(&st2);

regionLibrary.AddReader(&st3);

 

vlsuLibrary.AddReader(&lec1);

vlsuLibrary.AddReader(&lec2);

regionLibrary.AddReader(&lec1);

regionLibrary.AddReader(&lec2);

 

 

//

// Генерировать несколько печатных изданий и "продать" их библиотекам

//

for(int i = 0; i < 10; i++)

{

       IItem* item;

 

       // В половине случаев (i - четное) будем создавать журналы,

       // в половине - книги

       if (i % 2 == 0)

       {

             // Создать экземпляр журнала

             item = ItemFactory::Instance().CreateJournal();

       }

       else

       {

             // Создать экземпляр книги

             item = ItemFactory::Instance().CreateBook();

       }

 

       //

       // Библиотеки поочередно пытаются закупить печатное издание

       //

       bool isSold = false;

 

       if (!isSold)

       {

             isSold = vlsuLibrary.PurchaseItem(item);

       }

       if (!isSold)

       {

             isSold = regionLibrary.PurchaseItem(item);

       }

 

       //

       // Если экземпляр не куплен, надо его уничтожить, чтобы не было

       // мусора (в динамической памяти, а не в прямом смысле)

       //

       if (!isSold)

       {

             delete item;

       }

 

}

 

//

// Моделируем выдачу печатных изданий читателям

//

vlsuLibrary.LetLibItemOut(vlsuLibrary.GetLibItems()[0], &st1);

vlsuLibrary.LetLibItemOut(vlsuLibrary.GetLibItems()[1], &st1);

vlsuLibrary.LetLibItemOut(vlsuLibrary.GetLibItems()[2], &st2);

regionLibrary.LetLibItemOut(regionLibrary.GetLibItems()[0], &st3);

 

vlsuLibrary.LetLibItemOut(vlsuLibrary.GetLibItems()[3], &lec1);

regionLibrary.LetLibItemOut(regionLibrary.GetLibItems()[1], &lec1);

 

//

// Показать состояние библиотек и книг

//

 

Show(vlsuLibrary);

Show(regionLibrary);

 

return 0;

}

 

string DosString(string& winString)

{

// Буфер для преобразования

char * szStr = new char[winString.size()+1];

 

// Вызов CharToOemBuff - функции Windows API для преобразования

// Результат преобразования записывается в буфер

CharToOemBuff(winString.c_str(), szStr, DWORD(winString.size()+1));

 

return string(szStr);

}

 

string DosString(const char * const winString)

{

return DosString(string(winString));

}

 

 

void Show(Library& lib)

{

//

// Сведения о библиотеке

//

cout << "\n" << DosString(string("Название библиотеки: ")) <<

       DosString(lib.GetName()) << endl;

 

//

// Сведения о всех читателях библиотеки

//

cout << "\n" << DosString("Читатели:") << endl;

vector<Reader*> readers = lib.GetReaders();

for(int iReader = 0; iReader < readers.size(); iReader++)

{

       cout << iReader << ") " << DosString(readers[iReader]->GetName()) << endl;

}

 

 

//

// Сведения о книгах

//

cout << "\n" << DosString("Экземпляры:") << endl;

vector<LibraryItem*> items = lib.GetLibItems();

for(int i = 0; i < items.size(); i++)

{

       cout << i+1 << ") " << DosString(items[i]->GetTitle());

 

       // Вывести информацию, специфическую для конкретного типа издания

Book* book = dynamic_cast<Book*>(items[i]->GetItem());

       Journal* journal = dynamic_cast<Journal*>(items[i]->GetItem());

 

       if (book != NULL)

 

       {

             cout << DosString(" автор ") << DosString(book->GetAuthor());

       }

       else

       {

             if (journal != NULL)

             {

                   cout << DosString(" номер ") << DosString(journal->GetVolume());

             }

       }

 

       if (items[i]->GetReader() != NULL)

       {

             cout << DosString(" на руках: ")

                   << DosString(items[i]->GetReader()->GetName())

                   << DosString(" на ") << items[i]->GetHoldPeriod() << DosString(" дней")

                   << endl;

       }

       else

       {

             cout << DosString(" на полке") << endl;

       }

 

       cout

             << DosString("Инв.№ ") << items[i]->GetInventoryNumber()

             << DosString(" Стоимость ") << items[i]->GetPrice()

             << endl;

 

}

}

// PublicLibraryStrategy.cpp: implementation of the PublicLibraryStrategy class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "PublicLibraryStrategy.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

PublicLibraryStrategy::PublicLibraryStrategy(int nomianlHoldPeriod)

: _nomianlHoldPeriod(nomianlHoldPeriod)

{

 

}

 

PublicLibraryStrategy::~PublicLibraryStrategy()

{

 

}

 

int PublicLibraryStrategy::HoldPeriod(const Reader& reader) const

{

// Не зависимо от категории читателя, период для всех одинаковый

return _nomianlHoldPeriod;

}

// PurchaseCheapStrategy.cpp: implementation of the PurchaseCheapStrategy class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "PurchaseCheapStrategy.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

PurchaseCheapStrategy::PurchaseCheapStrategy(double maxPrice) : _maxPrice(maxPrice)

{

 

}

 

PurchaseCheapStrategy::~PurchaseCheapStrategy()

{

 

}

 

bool PurchaseCheapStrategy::IsAcceptable(const IItem& item)

{

bool result = true;

 

// Если цена более заданной максимальной,

// то закупка не приемлема

if (item.GetPrice() > _maxPrice)

{

       result = false;

}

return result;

}

// PurchaseExpensiveStrategy.cpp: implementation of the PurchaseExpensiveStrategy class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "PurchaseExpensiveStrategy.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

PurchaseExpensiveStrategy::PurchaseExpensiveStrategy(int minPrice)

: _minPrice(minPrice)

{

 

}

 

PurchaseExpensiveStrategy::~PurchaseExpensiveStrategy()

{

 

}

 

bool PurchaseExpensiveStrategy::IsAcceptable(const IItem &item)

{

bool result = true;

if (item.GetPrice() < _minPrice)

{

       result = false;

}

return result;

}

// Reader.cpp: implementation of the Reader class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Reader.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

Reader::Reader(const string& name) : _name(name)

{

 

}

 

Reader::~Reader()

{

 

}

 

string Reader::GetName()

{

return _name;

}

// stdafx.cpp : source file that includes just the standard includes

// PatternsApplication.pch will be the pre-compiled header

// stdafx.obj will contain the pre-compiled type information

 

#include "stdafx.h"

 

// TODO: reference any additional headers you need in STDAFX.H

// and not in this file

// Student.cpp: implementation of the Student class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Student.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

Student::Student(const string& name, int clazz)

: Reader(name), _class(clazz)

{

 

}

 

Student::~Student()

{

 

}

 

// UniversityLibraryStrategy.cpp: implementation of the UniversityLibraryStrategy class.

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "UniversityLibraryStrategy.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

UniversityLibraryStrategy::UniversityLibraryStrategy(int averagePeriod)

: _averagePeriod(averagePeriod)



  

© helpiks.su При использовании или копировании материалов прямая ссылка на сайт обязательна.