![]()
|
|||||||||||||||||||||||||||||||||
Лабораторная работа № 5 Основные положения объектно-ориентированного подходаЛабораторная работа № 5 Основные положения объектно-ориентированного подхода
Цель работы Изучить основные положения объектно-ориентированного подхода и освоить их использование в разработке программного обеспечения.
Порядок выполнения работы 1. В соответствии с вариантом задания разработать классы объектов реального мира. Из описания задачи выявить классы, абстракции сущностей, абстракции поведения. При необходимости самостоятельно вводить дополнительные абстракции так, чтобы модель была достаточно полной и непротиворечивой. Для упрощения задачи возможно уменьшение количества атрибутов классов. 2. Построить диаграмму классов для разрабатываемой программы. В разрабатываемой программе должны быть два вида отношения между объектами (использование и агрегирование), четыре вида зацепления объектов, все основные категории методов (конструктор, деструктор, модификатор, метод доступа). 3. Построить диаграммы взаимодействий и/или диаграммы последовательностей для детализации сложных взаимодействий. 4. Реализовать программу на языке программирования. В программе использовать все разработанные абстракции поведения классов. При необходимости корректировать диаграммы классов и объектов.
Содержание отчета 1. Цель работы. 2. Текст задания. 3. UML диаграмма классов. 4. UML диаграмма взаимодействий или диаграмма последовательностей для наиболее сложного случая взаимодействия экземпляров ролей классов. 5. Текст программы на языке C++ с указанием реализации отношений классов и объектов. 6. Копии выходных форм программы. 7. Выводы.
Контрольные вопросы 1. Использование объектов. 2. Агрегация объектов по ссылке и значению. 3. Наследование классов. 4. Ассоциации между классами. 5. Отношение зависимости между классами. 6. Абстрагирование. 7. Ограничение доступа.
Пример выполнения задания Перечень терминов предметной области:
Выполняем абстрагирование, при этом оставляем для книги только атрибут «название», и для простоты примера опускаем такие атрибуты книги как «автор книги», «год издания», «цена», «новизна издания», «аннотация». Для класса «Читатель» оставляем атрибут «ФИО», а вместо даты сдачи книги вводим «атрибут количество дней для чтения». Из перечня терминов предметной области не выявляется наследование классов, поэтому для демонстрации отношения наследования искусственно вводим две новые сущности: «Студент» и «Преподаватель», которые рассматриваем как частные случаи сущности «Читатель». Будем считать, что студенты забирают книгу на меньшее количество дней, чем преподаватели.
Рисунок 1 Диаграмма классов для примера "Библиотека"
Рисунок 2 Диаграмма взаимодействий для примера "Библиотека"
Рисунок 3 Диаграмма последовательностей для примера "Библиотека"
Исходный код программы см. в приложении. Выход программы показан на рисунке. Рисунок 4 Результат выполнения программы примера "Библиотека"
Варианты заданий
Приложение
// Book.h: interface for the Book class. // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_BOOK_H__D252336D_5C35_490A_8764_3E56FCEC782E__INCLUDED_) #define AFX_BOOK_H__D252336D_5C35_490A_8764_3E56FCEC782E__INCLUDED_
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#include <string>
using namespace std;
// // Класс экземпляров книг // class Book { public:
// Параметр название формируется из строки символов Book(const char* title);
virtual ~Book();
// Название книги (функция доступа) string GetTitle() const;
// Срок чтения (функция доступа) int GetHoldDurationDays() const;
// Изменить срок чтения (Мутатор) void SetHoldDurationDays(int value);
private:
// Название книги string _title;
// Срок чтения int _holdDurationDay; };
#endif
// !defined(AFX_BOOK_H__D252336D_5C35_490A_8764_3E56FCEC782E__INCLUDED_) // Book.cpp: implementation of the Book class. // //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "Book.h"
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
Book::Book(const char* title) : _title(title) {
}
Book::~Book() {
}
void Book::SetHoldDurationDays(int value) { _holdDurationDay = value; }
int Book::GetHoldDurationDays() const { return _holdDurationDay; }
string Book::GetTitle() const { return _title; }
// Reader.h: interface for the Reader class. // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_READER_H__E5387510_FEBB_4DF2_A475_3671E5C6F868__INCLUDED_) #define AFX_READER_H__E5387510_FEBB_4DF2_A475_3671E5C6F868__INCLUDED_
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#include <string> #include <list> #include "Book.h"
using namespace std;
// // Абстрактный класс читателей. Здесь полагаем, что // конкретные классы читателей различаются реализацией // абстракного метода TakeBookAway. // class Reader { public:
// При создании объекта задается имя читателя, которое не изменяется // на всем протяжении существования объекта. Reader(const string& name); virtual ~Reader();
// Абстрактный метод (в терминологии С++ - чистый виртуальный метод) void virtual TakeBookAway(Book& book) = 0;
// Вернуть книгу void GiveBookBack(Book& book);
// Дать список взятых книг. Фактически возвращается список // ссылок на взятые книги (метод доступа) const list<Book*>& GetTakenBooks() const;
// Получить имя читателя (метод доступа) const string& GetName() const;
protected: list<Book*> _takenBooks;
private:
// Имя - константное поле const string _name; };
#endif // !defined(AFX_READER_H__E5387510_FEBB_4DF2_A475_3671E5C6F868__INCLUDED_)
// Reader.cpp: implementation of the Reader class. // //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "Reader.h"
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
Reader::Reader(const string& name) : _name(name) {
}
Reader::~Reader() {
}
const string& Reader::GetName() const { return _name; }
const const list<Book*>& Reader::GetTakenBooks() const { return _takenBooks; }
void Reader::GiveBookBack(Book &book) { _takenBooks.remove(&book); }
// Lector.h: interface for the Lector class. // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_LECTOR_H__5D23E5A5_C1A3_4C2E_A52C_79C0E20B2903__INCLUDED_) #define AFX_LECTOR_H__5D23E5A5_C1A3_4C2E_A52C_79C0E20B2903__INCLUDED_
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#include "Reader.h"
// Конкретный класс Лектор - потомок абстрактного класса class Lector : public Reader { public: // Виртуальное замещение метода базвого абстрактного класса. void TakeBookAway(Book& book);
Lector(const string& name);
virtual ~Lector(); };
#endif // !defined(AFX_LECTOR_H__5D23E5A5_C1A3_4C2E_A52C_79C0E20B2903__INCLUDED_)
// Lector.cpp: implementation of the Lector class. // //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "Lector.h"
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
Lector::Lector(const string& name) : Reader(name) {
}
Lector::~Lector() {
}
void Lector::TakeBookAway(Book &book) {
// Установить срок, спеццифичный для данного класса book.SetHoldDurationDays(10);
// Запомнить адрес экземпляра "взятой" книги. _takenBooks.push_back(&book); }
// Student.h: interface for the Student class. // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_STUDENT_H__D58D3051_DDDF_443B_8B2A_44FB8FC6A0E2__INCLUDED_) #define AFX_STUDENT_H__D58D3051_DDDF_443B_8B2A_44FB8FC6A0E2__INCLUDED_
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#include "Reader.h"
// // Конкретный класс, производный от абстрактного класса читателей // class Student : public Reader { public:
// Реализация метода родительского класса void TakeBookAway(Book& book);
Student(const string& name);
virtual ~Student();
};
#endif // !defined(AFX_STUDENT_H__D58D3051_DDDF_443B_8B2A_44FB8FC6A0E2__INCLUDED_)
// Student.cpp: implementation of the Student class. // //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "Student.h"
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
Student::Student(const string& name) : Reader(name) {
}
Student::~Student() {
}
void Student::TakeBookAway(Book &book) { book.SetHoldDurationDays(3); _takenBooks.push_back(&book); }
// Library.h: interface for the Library class. // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_LIBRARY_H__D49015E9_2EEE_480D_8E5C_6B05BF4A2536__INCLUDED_) #define AFX_LIBRARY_H__D49015E9_2EEE_480D_8E5C_6B05BF4A2536__INCLUDED_
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#include <vector> #include "Reader.h" #include "Book.h"
// Для использования STL using namespace std;
class Library { public:
// В конструкторе формируется список книг. Такое решение - для // упрощения реализации Library();
virtual ~Library();
// Добавить ссылку на нового читателя void AddReader(Reader& reader);
// Выдать книгу читателю. void LetBookOut(Reader& reader, Book& book);
// Забрать книгу у читателя void PutBookBack(Reader& reader, Book& book);
// Вывести на монитор список всех книг в библиотеке и книг взятых читателями // с перечнем читателе (функция доступа) void PrintBookList() const;
// Получить список всех книг в библиотеке (функция доступа) vector<Book>& GetBooks();
private:
// Список книг - агрегация по значению vector<Book> _books;
// Список читателей - агрегация по ссылке (в терминах C++ - по адресу). vector<const Reader*> _readers;
};
#endif // !defined(AFX_LIBRARY_H__D49015E9_2EEE_480D_8E5C_6B05BF4A2536__INCLUDED_)
// Library.cpp: implementation of the Library class. // //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "Library.h"
#include <iostream> #include <sstream>
// Этот заголовочный файл содержит объявления функций Windows API // Здесь будет вызываться функция преобразования кодировок символов #include <windows.h>
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
Library::Library() { _books.push_back(Book("Война и мир")); _books.push_back(Book("Отцы и дети")); _books.push_back(Book("Принц и нищий")); _books.push_back(Book("Красное и черное")); _books.push_back(Book("Чук и Гек")); _books.push_back(Book("Алгебра и начала анализа")); }
Library::~Library() { }
void Library::PrintBookList() const { // // Информация в текстовом виде выводится в строковый поток. Это сделано для того, // чтобы в конце вывода преобразовать все символы в кодировку DOS. Т.к. текст // программы готовится в кодировке Windows, то и все символьные константы // оказываются в этой же кодировке. Приложение же разработано как консольное, и // выполняется в сеансе DOS. Поэтому и нужно преобразовать кодировку при выводе. //
// Строковый поток. Его класс является производным от ostream, поэтому для него // определены те же операторы вставки в поток. ostringstream str;
str << "Список книг\n";
for(int bIndex = 0; bIndex < _books.size(); bIndex++) { str << bIndex + 1 << ") " << _books[bIndex].GetTitle() << endl; }
str << "\nСписок читателей\n";
for(int rIndex = 0; rIndex < _readers.size(); rIndex++) { str << rIndex + 1 << ") " << _readers[rIndex]->GetName() << endl;
const list<Book*>& takenBooks = _readers[rIndex]->GetTakenBooks(); list<Book*>::const_iterator iter = takenBooks.begin(); int i = 0; for(; iter != takenBooks.end(); ++iter) { i++; str << " " << i << ") \"" << (*iter)->GetTitle() << "\" на " << (*iter)->GetHoldDurationDays() << " дней" << endl; } }
str << endl;
// Преобразовать строковый поток в строку для вывода string result = str.str();
// Буфер для преобразования char * szStr = new char[result.size()+1];
// Вызов CharToOemBuff - функции Windows API для преобразования // Результат преобразования записывается в буфер CharToOemBuff(result.c_str(), szStr, DWORD(result.size()+1));
// Вывод буфера в стандартный поток вывода cout << szStr << endl; }
void Library::LetBookOut(Reader& reader, Book& book) { // Чтобы книгу выдать, надо, чтобы читатель ее взял reader.TakeBookAway(book);
}
void Library::PutBookBack(Reader &reader, Book &book) { reader.GiveBookBack(book); }
void Library::AddReader(Reader& reader) { _readers.push_back(&reader); }
vector<Book>& Library::GetBooks() { return _books; }
|
|||||||||||||||||||||||||||||||||
|