Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Кашина_СП_ЛБ12

.docx
Скачиваний:
0
Добавлен:
22.09.2026
Размер:
168 Кб
Скачать

Министерство науки и высшего образования Российской Федерации Федеральное государственное бюджетное образовательное учреждение высшего образования

«Владимирский государственный университет

имени Александра Григорьевича и Николая Григорьевича Столетовых» (ВлГУ)

Колледж инновационных технологий и предпринимательства

КАФЕДРА ФИЗИКИ И ПРИКЛАДНОЙ МАТЕМАТИКИ

Лабораторная работа № 12

по дисциплине «Системное программирование»

на тему: «Шаблоны проектирования.»

Выполнил

студент группы ИПсп-123

Кашина Д. А.

Принял

Красильщикова В. В.

Владимир, 2026

Цель работы: получение практических навыков реализации шаблонов проектирования.

Задание:

Ход работы

person.h

#ifndef PERSON_H

#define PERSON_H

#include <string>

#include <stdexcept>

using namespace std;

struct Person {

string lastName;

string firstName;

int age;

char gender;

Person(const string& last = "", const string& first = "",

int a = 0, char g = 'M')

: lastName(last), firstName(first), age(a), gender(g) {

if (a < 0 || a > 150) {

throw invalid_argument("Некорректный возраст! Возраст должен быть от 0 до 150 лет.");

}

if (g != 'M' && g != 'F' && g != 'm' && g != 'f') {

throw invalid_argument("Некорректный пол! Используйте 'M' или 'F'.");

}

if (g == 'm') gender = 'M';

if (g == 'f') gender = 'F';

}

};

#endif

person_tree.h

#ifndef PERSON_TREE_H

#define PERSON_TREE_H

#include "person.h"

#include "person_state.h"

#include <vector>

#include <stdexcept>

#include <map>

using namespace std;

class DuplicatePersonException : public runtime_error {

public:

DuplicatePersonException(const string& msg) : runtime_error(msg) {}

};

class PersonNotFoundException : public runtime_error {

public:

PersonNotFoundException(const string& msg) : runtime_error(msg) {}

};

class PersonTree {

private:

struct Node {

Person data;

PersonContext* stateContext;

Node* left;

Node* right;

Node(const Person& p);

~Node();

};

Node* root;

// Вспомогательные методы

Node* add(Node* node, const Person& person);

Node* remove(Node* node, const Person& person);

Node* findMin(Node* node);

void clear(Node* node);

void toArray(Node* node, vector<Person>& arr);

void toArrayWithStates(Node* node, vector<pair<Person, string>>& arr);

bool compareByKey(const Person& a, const Person& b);

bool equalsByKey(const Person& a, const Person& b);

Node* findByKey(Node* node, const Person& person);

bool searchByAge(Node* node, int age);

bool searchByLastName(Node* node, const string& lastName);

public:

PersonTree();

~PersonTree();

void add(const Person& person);

void remove(const Person& person);

bool existsByFullKey(const Person& person);

bool existsByAge(int age);

bool existsByLastName(const string& lastName);

vector<Person> getAll();

vector<pair<Person, string>> getAllWithStates();

bool isEmpty() const { return root == nullptr; }

string performActionOnPerson(const Person& person, const string& action);

vector<string> performActionOnAll(const string& action);

map<string, int> getStatesStatistics();

};

#endif

person_tree.cpp

#include "person_tree.h"

#include <iostream> // для отладки

PersonTree::Node::Node(const Person& p) : data(p), left(nullptr), right(nullptr) {

stateContext = new PersonContext(p.firstName + " " + p.lastName);

stateContext->setState(new HealthyState()); // По умолчанию здоров

}

PersonTree::Node::~Node() {

delete stateContext;

}

PersonTree::PersonTree() : root(nullptr) {}

PersonTree::~PersonTree() {

clear(root);

}

void PersonTree::clear(Node* node) {

if (!node) return;

clear(node->left);

clear(node->right);

delete node;

}

bool PersonTree::compareByKey(const Person& a, const Person& b) {

if (a.age != b.age) return a.age < b.age;

return a.lastName < b.lastName;

}

bool PersonTree::equalsByKey(const Person& a, const Person& b) {

return a.age == b.age && a.lastName == b.lastName;

}

PersonTree::Node* PersonTree::add(Node* node, const Person& person) {

if (!node) return new Node(person);

if (equalsByKey(person, node->data))

throw DuplicatePersonException("Человек с таким возрастом и фамилией уже существует!");

if (compareByKey(person, node->data))

node->left = add(node->left, person);

else

node->right = add(node->right, person);

return node;

}

void PersonTree::add(const Person& person) {

root = add(root, person);

}

PersonTree::Node* PersonTree::findMin(Node* node) {

while (node->left) node = node->left;

return node;

}

PersonTree::Node* PersonTree::remove(Node* node, const Person& person) {

if (!node) throw PersonNotFoundException("Человек с указанным возрастом и фамилией не найден!");

if (compareByKey(person, node->data))

node->left = remove(node->left, person);

else if (compareByKey(node->data, person))

node->right = remove(node->right, person);

else {

if (!node->left && !node->right) {

delete node;

return nullptr;

}

if (!node->left) {

Node* temp = node->right;

delete node;

return temp;

}

if (!node->right) {

Node* temp = node->left;

delete node;

return temp;

}

Node* minNode = findMin(node->right);

// СОХРАНЯЕМ состояние перед заменой

PersonContext* oldContext = node->stateContext;

node->data = minNode->data;

// СОХРАНЯЕМ состояние для нового узла

delete node->stateContext;

node->stateContext = new PersonContext(minNode->data.firstName + " " + minNode->data.lastName);

// КОПИРУЕМ состояние из minNode

string currentStateName = minNode->stateContext->getCurrentStateName();

if (currentStateName == "Здоров") {

node->stateContext->setState(new HealthyState());

}

else if (currentStateName == "Болеет") {

node->stateContext->setState(new SickState());

}

else if (currentStateName == "Работает") {

node->stateContext->setState(new WorkingState());

}

else if (currentStateName == "Учится") {

node->stateContext->setState(new StudyingState());

}

else {

node->stateContext->setState(new HealthyState());

}

node->right = remove(node->right, minNode->data);

}

return node;

}

void PersonTree::remove(const Person& person) {

root = remove(root, person);

}

PersonTree::Node* PersonTree::findByKey(Node* node, const Person& person) {

if (!node) return nullptr;

if (equalsByKey(person, node->data)) return node;

if (compareByKey(person, node->data)) return findByKey(node->left, person);

return findByKey(node->right, person);

}

bool PersonTree::existsByFullKey(const Person& person) {

return findByKey(root, person) != nullptr;

}

bool PersonTree::searchByAge(Node* node, int age) {

if (!node) return false;

if (node->data.age == age) return true;

return searchByAge(node->left, age) || searchByAge(node->right, age);

}

bool PersonTree::existsByAge(int age) {

return searchByAge(root, age);

}

bool PersonTree::searchByLastName(Node* node, const string& lastName) {

if (!node) return false;

if (node->data.lastName == lastName) return true;

return searchByLastName(node->left, lastName) || searchByLastName(node->right, lastName);

}

bool PersonTree::existsByLastName(const string& lastName) {

return searchByLastName(root, lastName);

}

void PersonTree::toArray(Node* node, vector<Person>& arr) {

if (!node) return;

toArray(node->left, arr);

arr.push_back(node->data);

toArray(node->right, arr);

}

vector<Person> PersonTree::getAll() {

vector<Person> arr;

toArray(root, arr);

return arr;

}

void PersonTree::toArrayWithStates(Node* node, vector<pair<Person, string>>& arr) {

if (!node) return;

toArrayWithStates(node->left, arr);

arr.push_back({ node->data, node->stateContext->getCurrentStateName() });

toArrayWithStates(node->right, arr);

}

vector<pair<Person, string>> PersonTree::getAllWithStates() {

vector<pair<Person, string>> arr;

toArrayWithStates(root, arr);

return arr;

}

string PersonTree::performActionOnPerson(const Person& person, const string& action) {

Node* node = findByKey(root, person);

if (!node) throw PersonNotFoundException("Человек не найден!");

// ОТЛАДКА: выводим текущее состояние

cout << "[DEBUG] Текущее состояние: " << node->stateContext->getCurrentStateName() << endl;

cout << "[DEBUG] Выполняем действие: " << action << endl;

string result = node->stateContext->performAction(action);

// ОТЛАДКА: выводим новое состояние

cout << "[DEBUG] Новое состояние: " << node->stateContext->getCurrentStateName() << endl;

return result;

}

vector<string> PersonTree::performActionOnAll(const string& action) {

vector<string> results;

vector<pair<Person, string>> persons = getAllWithStates();

for (auto& p : persons) {

Node* node = findByKey(root, p.first);

if (node) {

results.push_back(node->stateContext->performAction(action));

}

}

return results;

}

map<string, int> PersonTree::getStatesStatistics() {

map<string, int> stats;

vector<pair<Person, string>> persons = getAllWithStates();

for (auto& p : persons) {

stats[p.second]++;

}

return stats;

}

person_state.h

#ifndef PERSON_STATE_H

#define PERSON_STATE_H

#include <iostream>

#include <string>

using namespace std;

class PersonContext;

class PersonState {

public:

virtual ~PersonState() = default;

virtual string getActionDescription(const string& name, const string& action) const = 0;

virtual string getStateName() const = 0;

virtual PersonState* handleEvent(const string& event) = 0;

};

class PersonContext {

private:

PersonState* currentState;

string name;

public:

PersonContext(const string& personName);

~PersonContext();

void setState(PersonState* state);

string performAction(const string& action);

string getCurrentStateName() const;

string getName() const;

};

class HealthyState : public PersonState {

public:

string getActionDescription(const string& name, const string& action) const override;

string getStateName() const override;

PersonState* handleEvent(const string& event) override;

};

class SickState : public PersonState {

public:

string getActionDescription(const string& name, const string& action) const override;

string getStateName() const override;

PersonState* handleEvent(const string& event) override;

};

class WorkingState : public PersonState {

public:

string getActionDescription(const string& name, const string& action) const override;

string getStateName() const override;

PersonState* handleEvent(const string& event) override;

};

class StudyingState : public PersonState {

public:

string getActionDescription(const string& name, const string& action) const override;

string getStateName() const override;

PersonState* handleEvent(const string& event) override;

};

// RestState объявлен ТОЛЬКО ЗДЕСЬ

class RestState : public PersonState {

public:

string getActionDescription(const string& name, const string& action) const override;

string getStateName() const override;

PersonState* handleEvent(const string& event) override;

};

#endif

person_tree.cpp

#include "person_state.h"

PersonContext::PersonContext(const string& personName) : name(personName), currentState(nullptr) {}

PersonContext::~PersonContext() {

delete currentState;

}

void PersonContext::setState(PersonState* state) {

if (currentState) delete currentState;

currentState = state;

}

string PersonContext::performAction(const string& action) {

if (currentState) {

PersonState* newState = currentState->handleEvent(action);

if (newState != currentState) {

setState(newState);

}

return currentState->getActionDescription(name, action);

}

return "Состояние не установлено!";

}

string PersonContext::getCurrentStateName() const {

return currentState ? currentState->getStateName() : "Не установлено";

}

string PersonContext::getName() const {

return name;

}

// ============ HealthyState ============

string HealthyState::getActionDescription(const string& name, const string& action) const {

if (action == "walk") return name + " гуляет и остаётся здоровым!";

if (action == "work") return name + " начинает работать!";

if (action == "study") return name + " начинает учиться!";

if (action == "sick") return name + " заболел(а)!";

if (action == "treat") return name + " уже здоров(а), лечение не нужно!";

if (action == "rest") return name + " отдыхает!";

return name + " чувствует себя отлично!";

}

string HealthyState::getStateName() const {

return "Здоров";

}

PersonState* HealthyState::handleEvent(const string& event) {

if (event == "walk") return new HealthyState();

if (event == "work") return new WorkingState();

if (event == "study") return new StudyingState();

if (event == "sick") return new SickState();

if (event == "treat") return new HealthyState();

if (event == "rest") return new RestState();

return this;

}

// ============ SickState ============

string SickState::getActionDescription(const string& name, const string& action) const {

if (action == "walk") return name + " не может гулять, он(а) болеет!";

if (action == "work") return name + " не может работать из-за болезни!";

if (action == "study") return name + " не может учиться из-за болезни!";

if (action == "sick") return name + " уже болеет!";

if (action == "treat") return name + " лечится и выздоравливает!";

if (action == "rest") return name + " отдыхает, чтобы выздороветь!";

return name + " плохо себя чувствует.";

}

string SickState::getStateName() const {

return "Болеет";

}

PersonState* SickState::handleEvent(const string& event) {

if (event == "walk") return this;

if (event == "work") return this;

if (event == "study") return this;

if (event == "sick") return this;

if (event == "treat") return new HealthyState();

if (event == "rest") return new RestState();

return this;

}

// ============ WorkingState ============

string WorkingState::getActionDescription(const string& name, const string& action) const {

if (action == "walk") return name + " не может гулять, он(а) работает!";

if (action == "work") return name + " уже работает!";

if (action == "study") return name + " не может учиться, он(а) работает!";

if (action == "sick") return name + " заболел(а) на работе!";

if (action == "treat") return name + " нужно лечиться, а не работать!";

if (action == "rest") return name + " отдыхает после работы!";

return name + " занят работой.";

}

string WorkingState::getStateName() const {

return "Работает";

}

PersonState* WorkingState::handleEvent(const string& event) {

if (event == "walk") return this;

if (event == "work") return this;

if (event == "study") return this;

if (event == "sick") return new SickState();

if (event == "treat") return this;

if (event == "rest") return new RestState();

return this;

}

// ============ StudyingState ============

string StudyingState::getActionDescription(const string& name, const string& action) const {

if (action == "walk") return name + " не может гулять, он(а) учится!";

if (action == "work") return name + " не может работать, он(а) учится!";

if (action == "study") return name + " уже учится!";

if (action == "sick") return name + " заболел(а) из-за учёбы!";

if (action == "treat") return name + " нужно лечиться, а не учиться!";

if (action == "rest") return name + " отдыхает после учёбы!";

return name + " занят учёбой.";

}

string StudyingState::getStateName() const {

return "Учится";

}

PersonState* StudyingState::handleEvent(const string& event) {

if (event == "walk") return this;

if (event == "work") return this;

if (event == "study") return this;

if (event == "sick") return new SickState();

if (event == "treat") return this;

if (event == "rest") return new RestState();

return this;

}

// ============ RestState - ТОЛЬКО РЕАЛИЗАЦИЯ МЕТОДОВ, НЕ ОПРЕДЕЛЕНИЕ КЛАССА! ============

string RestState::getActionDescription(const string& name, const string& action) const {

if (action == "walk") return name + " гуляет и отдыхает!";

if (action == "work") return name + " начинает работать после отдыха!";

if (action == "study") return name + " начинает учиться после отдыха!";

if (action == "sick") return name + " заболел(а) во время отдыха!";

if (action == "treat") return name + " лечится, но лучше отдыхать!";

if (action == "rest") return name + " уже отдыхает!";

return name + " наслаждается отдыхом.";

}

string RestState::getStateName() const {

return "Отдыхает";

}

PersonState* RestState::handleEvent(const string& event) {

if (event == "walk") return new HealthyState();

if (event == "work") return new WorkingState();

if (event == "study") return new StudyingState();

if (event == "sick") return new SickState();

if (event == "treat") return new HealthyState();

if (event == "rest") return this;

return this;

}

person_decorator.h

#ifndef PERSON_DECORATOR_H

#define PERSON_DECORATOR_H

#include "person.h"

#include <iostream>

using namespace std;

// Базовый интерфейс

class PersonInterface {

public:

virtual ~PersonInterface() = default;

virtual void describe() const = 0;

virtual string getInfo() const = 0;

};

// Адаптер для структуры Person

class PersonAdapter : public PersonInterface {

protected:

Person person;

public:

PersonAdapter(const Person& p) : person(p) {}

void describe() const override {

cout << getInfo();

}

string getInfo() const override {

return "Человек: " + person.lastName + " " + person.firstName +

", возраст: " + to_string(person.age) +

", пол: " + (person.gender == 'M' ? "Мужской" : "Женский");

}

Person getPerson() const {

return person;

}

};

// Базовый класс декоратора

class PersonDecorator : public PersonInterface {

protected:

PersonInterface* wrapped;

public:

PersonDecorator(PersonInterface* p) : wrapped(p) {}

virtual ~PersonDecorator() {

delete wrapped;

}

void describe() const override {

wrapped->describe();

}

string getInfo() const override {

return wrapped->getInfo();

}

};

// Конкретный декоратор: Студент

class StudentDecorator : public PersonDecorator {

private:

string university;

string group;

double averageGrade;

public:

StudentDecorator(PersonInterface* p, const string& uni, const string& grp, double grade)

: PersonDecorator(p), university(uni), group(grp), averageGrade(grade) {}

void describe() const override {

cout << getInfo();

}

string getInfo() const override {

return PersonDecorator::getInfo() +

"\n - Студент университета: " + university +

"\n - Группа: " + group +

"\n - Средний балл: " + to_string(averageGrade);

}

};

// Конкретный декоратор: Работник

class WorkerDecorator : public PersonDecorator {

private:

string company;

string position;

double salary;

public:

WorkerDecorator(PersonInterface* p, const string& comp, const string& pos, double sal)

: PersonDecorator(p), company(comp), position(pos), salary(sal) {}

void describe() const override {

cout << getInfo();

}

string getInfo() const override {

return PersonDecorator::getInfo() +

"\n - Работник компании: " + company +

"\n - Должность: " + position +

"\n - Зарплата: " + to_string(salary) + " руб.";

}

};

// Конкретный декоратор: Спортсмен

class AthleteDecorator : public PersonDecorator {

private:

string sport;

string rank;

int medalsCount;

public:

AthleteDecorator(PersonInterface* p, const string& sp, const string& r, int medals)

: PersonDecorator(p), sport(sp), rank(r), medalsCount(medals) {}

void describe() const override {

cout << getInfo();

}

string getInfo() const override {

return PersonDecorator::getInfo() +

"\n - Спортсмен, вид спорта: " + sport +

"\n - Разряд: " + rank +

"\n - Количество медалей: " + to_string(medalsCount);

}

};

#endif

person_builder.h

#ifndef PERSON_BUILDER_H

#define PERSON_BUILDER_H

#include "person.h"

// Строитель для создания Person

class PersonBuilder {

private:

string lastName;

string firstName;

int age;

char gender;

public:

PersonBuilder() : lastName(""), firstName(""), age(0), gender('M') {}

PersonBuilder& setLastName(const string& last) {

lastName = last;

return *this;

}

PersonBuilder& setFirstName(const string& first) {

firstName = first;

return *this;

}

PersonBuilder& setAge(int a) {

age = a;

return *this;

}

PersonBuilder& setGender(char g) {

gender = g;

return *this;

}

Person build() {

return Person(lastName, firstName, age, gender);

}

};

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

class PersonDirector {

public:

static Person createStudent(const string& last, const string& first, int age) {

return PersonBuilder()

.setLastName(last)

.setFirstName(first)

.setAge(age)

.setGender('M')

.build();

}

static Person createTeacher(const string& last, const string& first, int age) {

return PersonBuilder()

.setLastName(last)

.setFirstName(first)

.setAge(age)

.setGender('F')

.build();

}

static Person createChild(const string& last, const string& first, int age) {

return PersonBuilder()

.setLastName(last)

.setFirstName(first)

.setAge(age)

.setGender('M')

.build();

}

};

#endif

main.cpp

#include <iostream>

#include <iomanip>

#include <windows.h>

#include <limits>

#include <vector>

#include "person_tree.h"

using namespace std;

// ==================== ФУНКЦИИ ВВОДА/ВЫВОДА ====================

void setRussianConsole() {

SetConsoleOutputCP(1251);

SetConsoleCP(1251);

}

void clearInput() {

cin.clear();

cin.ignore(10000, '\n');

}

void clearScreen() {

system("cls");

}

int inputAge() {

int age;

while (true) {

cout << "Введите возраст (0-150): ";

if (cin >> age) {

if (age >= 0 && age <= 150) return age;

cout << "Ошибка! Возраст должен быть от 0 до 150.\n";

}

else {

cout << "Ошибка! Введите целое число.\n";

clearInput();

}

}

}

char inputGender() {

char gender;

while (true) {

cout << "Введите пол (M/F): ";

cin >> gender;

if (gender == 'M' || gender == 'm' || gender == 'F' || gender == 'f') {

return toupper(gender);

}

cout << "Ошибка! Введите 'M' или 'F'.\n";

clearInput();

}

}

string inputString(const string& prompt) {

string str;

while (true) {

cout << prompt;

cin >> str;

if (!str.empty()) return str;

cout << "Ошибка! Строка не может быть пустой.\n";

}

}

Person inputPerson() {

Person p;

p.lastName = inputString("Введите фамилию: ");

p.firstName = inputString("Введите имя: ");

p.age = inputAge();

p.gender = inputGender();

return p;

}

Person inputPersonKey() {

Person p;

p.lastName = inputString("Введите фамилию: ");

p.age = inputAge();

return p;

}

void printTableHeader() {

cout << "+--------------+------------+--------+----------+------------------+\n";

cout << "| " << left << setw(12) << "Фамилия"

<< " | " << setw(10) << "Имя"

<< " | " << setw(6) << "Возраст"

<< " | " << setw(8) << "Пол"

<< " | " << setw(16) << "Состояние"

<< " |\n";

cout << "+--------------+------------+--------+----------+------------------+\n";

}

void printPersonRow(const Person& p, const string& state) {

cout << "| " << left << setw(12) << p.lastName

<< " | " << setw(10) << p.firstName

<< " | " << setw(6) << p.age

<< " | " << setw(8) << (p.gender == 'M' ? "Муж" : "Жен")

<< " | " << setw(16) << state

<< " |\n";

cout << "+--------------+------------+--------+----------+------------------+\n";

}

void printAllPersons(PersonTree& tree) {

vector<pair<Person, string>> persons = tree.getAllWithStates();

if (persons.empty()) {

cout << "\n*** В базе данных нет людей ***\n";

return;

}

cout << "\n==================== ВСЕ ЛЮДИ ====================\n";

printTableHeader();

for (const auto& p : persons) {

printPersonRow(p.first, p.second);

}

cout << "Всего людей: " << persons.size() << "\n";

}

string getActionChoice() {

cout << "\nВыберите действие:\n";

cout << " 1. Гулять (walk)\n";

cout << " 2. Работать (work)\n";

cout << " 3. Учиться (study)\n";

cout << " 4. Болеть (sick)\n";

cout << " 5. Лечиться (treat)\n";

cout << " 6. Отдыхать (rest)\n";

cout << "Ваш выбор: ";

int choice;

cin >> choice;

switch (choice) {

case 1: return "walk";

case 2: return "work";

case 3: return "study";

case 4: return "sick";

case 5: return "treat";

case 6: return "rest";

default: return "walk";

}

}

// ==================== ДЕМОНСТРАЦИЯ ПАТТЕРНОВ ====================

void demoBuilder() {

clearScreen();

cout << "\n========== ПАТТЕРН «СТРОИТЕЛЬ» (BUILDER) ==========\n\n";

class Builder {

string last, first;

int age;

char gender;

public:

Builder() : last(""), first(""), age(0), gender('M') {}

Builder& setLast(string l) { last = l; return *this; }

Builder& setFirst(string f) { first = f; return *this; }

Builder& setAge(int a) { age = a; return *this; }

Builder& setGender(char g) { gender = g; return *this; }

Person build() { return Person(last, first, age, gender); }

};

Person p1 = Builder().setLast("Сидоров").setFirst("Алексей").setAge(20).setGender('M').build();

Person p2 = Builder().setLast("Петрова").setFirst("Мария").setAge(19).setGender('F').build();

cout << "Создано через Builder:\n";

cout << " " << p1.lastName << " " << p1.firstName << ", " << p1.age << " лет\n";

cout << " " << p2.lastName << " " << p2.firstName << ", " << p2.age << " лет\n";

cout << "\nПреимущество: пошаговое создание объекта\n";

}

void demoDecorator() {

clearScreen();

cout << "\n========== ПАТТЕРН «ДЕКОРАТОР» (DECORATOR) ==========\n\n";

class Info {

public:

virtual ~Info() {}

virtual string get() const = 0;

};

class SimpleInfo : public Info {

Person p;

public:

SimpleInfo(const Person& person) : p(person) {}

string get() const override {

return p.lastName + " " + p.firstName + ", " + to_string(p.age) + " лет";

}

};

class StudentDecorator : public Info {

Info* wrapped;

public:

StudentDecorator(Info* w) : wrapped(w) {}

~StudentDecorator() { delete wrapped; }

string get() const override {

return wrapped->get() + " [Студент МГУ]";

}

};

Person test("Иванов", "Иван", 25, 'M');

Info* basic = new SimpleInfo(test);

cout << "Базовый: " << basic->get() << endl;

Info* student = new StudentDecorator(basic);

cout << "С декором: " << student->get() << endl;

delete student;

}

// ==================== ГЛАВНОЕ МЕНЮ ====================

void showMenu() {

cout << "\n";

cout << "+========================================================+\n";

cout << "| СИСТЕМА УПРАВЛЕНИЯ ЛЮДЬМИ |\n";

cout << "| (паттерны: Состояние, Строитель, Декоратор) |\n";

cout << "+========================================================+\n";

cout << "| 1. Добавить человека |\n";

cout << "| 2. Удалить человека |\n";

cout << "| 3. Найти по возрасту+фамилии |\n";

cout << "| 4. Найти по возрасту |\n";

cout << "| 5. Найти по фамилии |\n";

cout << "| 6. Показать всех |\n";

cout << "+========================================================+\n";

cout << "| 7. ПАТТЕРН «СОСТОЯНИЕ» - действие над человеком |\n";

cout << "| 8. ПАТТЕРН «СТРОИТЕЛЬ» - демонстрация |\n";

cout << "| 9. ПАТТЕРН «ДЕКОРАТОР» - демонстрация |\n";

cout << "+========================================================+\n";

cout << "| 0. Выход |\n";

cout << "+========================================================+\n";

cout << "Ваш выбор: ";

}

// ==================== MAIN ====================

int main() {

setRussianConsole();

PersonTree tree;

int choice;

// Тестовые данные

try {

tree.add(Person("Иванов", "Иван", 25, 'M'));

tree.add(Person("Петрова", "Мария", 30, 'F'));

tree.add(Person("Сидоров", "Алексей", 25, 'M'));

cout << "\n*** Добавлены тестовые данные ***\n";

}

catch (const exception& e) {

cout << "Ошибка: " << e.what() << endl;

}

do {

showMenu();

if (!(cin >> choice)) {

cout << "Ошибка! Введите число.\n";

clearInput();

continue;

}

try {

switch (choice) {

case 1: {

clearScreen();

cout << "\n--- ДОБАВЛЕНИЕ ЧЕЛОВЕКА ---\n";

Person p = inputPerson();

tree.add(p);

cout << "\n*** Человек добавлен! ***\n";

break;

}

case 2: {

clearScreen();

cout << "\n--- УДАЛЕНИЕ ЧЕЛОВЕКА ---\n";

Person p = inputPersonKey();

tree.remove(p);

cout << "\n*** Человек удалён! ***\n";

break;

}

case 3: {

clearScreen();

cout << "\n--- ПОИСК ПО КЛЮЧУ ---\n";

Person p = inputPersonKey();

if (tree.existsByFullKey(p)) {

cout << "\n*** Человек НАЙДЕН! ***\n";

}

else {

cout << "\n*** Человек НЕ НАЙДЕН ***\n";

}

break;

}

case 4: {

clearScreen();

cout << "\n--- ПОИСК ПО ВОЗРАСТУ ---\n";

int age = inputAge();

if (tree.existsByAge(age)) {

cout << "\n*** Есть человек с возрастом " << age << " лет! ***\n";

}

else {

cout << "\n*** Нет человека с возрастом " << age << " лет! ***\n";

}

break;

}

case 5: {

clearScreen();

cout << "\n--- ПОИСК ПО ФАМИЛИИ ---\n";

string last = inputString("Введите фамилию: ");

if (tree.existsByLastName(last)) {

cout << "\n*** Есть человек с фамилией '" << last << "'! ***\n";

}

else {

cout << "\n*** Нет человека с фамилией '" << last << "'! ***\n";

}

break;

}

case 6: {

clearScreen();

printAllPersons(tree);

break;

}

case 7: {

clearScreen();

cout << "\n========== ПАТТЕРН «СОСТОЯНИЕ» ==========\n\n";

vector<pair<Person, string>> persons = tree.getAllWithStates();

if (persons.empty()) {

cout << "*** Нет людей! ***\n";

break;

}

cout << "Доступные люди:\n";

printTableHeader();

for (const auto& p : persons) {

printPersonRow(p.first, p.second);

}

cout << "\nВыберите человека:\n";

Person p = inputPersonKey();

if (!tree.existsByFullKey(p)) {

cout << "\n*** Человек не найден! ***\n";

break;

}

string action = getActionChoice();

string result = tree.performActionOnPerson(p, action);

cout << "\n============================================\n";

cout << "РЕЗУЛЬТАТ: " << result << "\n";

cout << "============================================\n";

break;

}

case 8: {

demoBuilder();

break;

}

case 9: {

demoDecorator();

break;

}

case 0: {

clearScreen();

cout << "\n*** Выход из программы... ***\n";

break;

}

default: {

cout << "\n*** Неверный выбор! ***\n";

break;

}

}

}

catch (DuplicatePersonException& e) {

cout << "\n!!! ОШИБКА: " << e.what() << " !!!\n";

}

catch (PersonNotFoundException& e) {

cout << "\n!!! ОШИБКА: " << e.what() << " !!!\n";

}

catch (exception& e) {

cout << "\n!!! ОШИБКА: " << e.what() << " !!!\n";

}

if (choice != 0 && choice != 6 && choice != 8 && choice != 9) {

cout << "\nНажмите Enter для продолжения...";

cin.ignore();

cin.get();

}

} while (choice != 0);

return 0;

}

Диаграмма UML

Вывод: в ходе лабораторной работы получены практические навыки реализации шаблонов проектирования

Соседние файлы в предмете Системное программирование