
Лаб. 6 ПиАПС
.docxЛ а б о р а т о р н а я р а б о т а № 6
«Реализация одного из паттернов поведения»
Цель работы: Применение паттерна проектирования Observer (наблюдатель)
#include <iostream>
#include <regex>
#include <string>
#include <list>
#include <map>
using namespace std;
class ISubject;
class IObserver {
public:
virtual ~IObserver() = default;
virtual void update(ISubject*, string) = 0;
};
class ISubject {
public:
virtual ~ISubject() = default;
virtual void attach(IObserver*) = 0;
virtual void detach(IObserver*) = 0;
virtual void notify() = 0;
};
class Teacher : public ISubject {
string name;
string currentAcademicPerformance;
list<IObserver*> observers;
public:
Teacher(string name) : name(name) {}
string getName() { return name; }
void createCurrentAcademicPerformance(string currentAcademicPerformance = "") {
this->currentAcademicPerformance = currentAcademicPerformance;
notify(); // Уведомление деканата
}
void attach(IObserver* observer) override {
observers.push_back(observer);
}
void detach(IObserver* observer) override {
observers.remove(observer);
}
void notify() override {
for (auto observer : observers) {
observer->update(this, currentAcademicPerformance);
}
}
};
class DeansOffice : public IObserver, ISubject {
list<Teacher*> subscriptions;
list<IObserver*> observers;
string reportMessage;
public:
void update(ISubject* subject, string currentAcademicPerformance) override {
Teacher* teacher = dynamic_cast<Teacher*>(subject);
if (teacher) {
printInfo(teacher->getName(), currentAcademicPerformance);
}
}
void printInfo(string teacherName, string currentAcademicPerformance) {
if (currentAcademicPerformance.empty()) {
reportMessage = "Преподаватель " + teacherName + " не сдал текущую успеваемость!";
cout << "Деканат: " << reportMessage << " Уведомляем кафедру!" << endl;
notify(); // Уведомление кафедры
}
else {
cout << "Деканат: Получена успеваемость от преподавателя "
<< teacherName << ": " << currentAcademicPerformance << endl;
}
}
void subscribeTo(Teacher* teacher) {
teacher->attach(this);
subscriptions.push_back(teacher);
cout << "Деканат подписался на преподавателя " << teacher->getName() << endl;
}
/*void unsubscribeFrom(const string& name) {
auto it = find_if(subscriptions.begin(), subscriptions.end(),
[&name](Teacher* t) { return t->getName() == name; });
if (it != subscriptions.end()) {
(*it)->detach(this);
cout << "Деканат отписался от преподавателя " << (*it)->getName() << endl;
subscriptions.erase(it);
}
}*/
void unsubscribeFrom(Teacher* teacher) {
teacher->detach(this);
subscriptions.remove(teacher);
cout << "Деканат отписался от преподавателя " << teacher->getName() << endl;
}
void unsubscribeFromAll() {
for (auto teacher : subscriptions) {
teacher->detach(this);
cout << "Деканат отписался от преподавателя " << teacher->getName() << endl;
}
subscriptions.clear();
}
void attach(IObserver* observer) override {
observers.push_back(observer);
}
void detach(IObserver* observer) override {
observers.remove(observer);
}
void notify() override {
for (auto observer : observers) {
observer->update(this, reportMessage);
}
}
};
class Department : public IObserver {
DeansOffice* deansOffice = nullptr;
public:
void update(ISubject* subject, string message) override {
cout << "Кафедра получила сообщение от деканата: " << message << endl;
}
void subscribeTo(DeansOffice* deansOffice) {
this->deansOffice = deansOffice;
deansOffice->attach(this);
cout << "Кафедра подписалась на деканат" << endl;
}
void unsubscribe() {
if (deansOffice) {
deansOffice->detach(this);
cout << "Кафедра отписалась от деканата" << endl;
deansOffice = nullptr;
}
}
};
int main() {
setlocale(LC_ALL, "rus");
Teacher teacher1("Иванов");
Teacher teacher2("Петров");
Teacher teacher3("Сидоров");
DeansOffice deansOffice;
Department department;
department.subscribeTo(&deansOffice);
deansOffice.subscribeTo(&teacher1);
deansOffice.subscribeTo(&teacher2);
deansOffice.subscribeTo(&teacher3);
teacher1.createCurrentAcademicPerformance("Средний балл студентов: 4.2");
teacher2.createCurrentAcademicPerformance();
teacher3.createCurrentAcademicPerformance("Средний балл студентов: 4.5");
// deansOffice.unsubscribeFrom("Петров");
deansOffice.unsubscribeFrom(&teacher2);
teacher2.createCurrentAcademicPerformance("Средний балл студентов: 3.8");
deansOffice.unsubscribeFromAll();
department.unsubscribe();
return 0;
}