Obiekt Logger odpowiada za przesłanie komunikatów, użytkownik woła metodę msg przekazując treść komunikatu. Treść ta jest zapisywana do odpowiednich miejsc, w zależności od konfiguracji. Przedstawione poniżej rozwiązanie ma pewne ograniczenia: (1) klasa jest zależna jest od wszystkich klas reprezentujących odbiorców komunikatu (Mail, File, cerr), (2) konfiguracja odbiorców komunikatów jest ogrniczona, na przykład nie można zapisywać do więcej niż trzech plików, nie można wyłączyć wysyłania komunikatów na strumień cerr ('cerr' obiekt reprezentujący standardowy strumień znakowy błędów).
//Klasa pomocnicza, jej nie zmieniamy class File { public: File(const std::string& file_name); void write(const std::string& msg); }; //Klasa pomocnicza, jej nie zmieniamy class Mail { public: Mail(const std::string& address) {} void send(const std::string& msg) {} }; class Logger { public: Logger() : file1(nullptr), file2(nullptr), mail(nullptr) {} void setFile1(File* f) { file1 = f; } void setFile2(File* f) { file2 = f; } void setMail(Mail* e) { mail = e; } int msg(const string& msg) { std::cerr << msg << std::endl; if(file1) file1->write(msg); if(file2) file2->write(msg); if(mail) mail->send(msg); } private: File* file1; File* file2; Mail* mail; };
Proszę odpowiedz na poniższe pytania:
class Observer { public: virtual void notify(const string& msg) = 0; }; class FileObs : public Observer { public: FileObs(const string& file_name) : f_(file_name) {} virtual void notify(const string& msg) { f_.write(msg); } private: File f_; }; class MailObs : public Observer { public: MailObs(const string& address) : m_(address) {} virtual void notify(const string& msg) { m_.send(msg); } private: Mail m_; }; class StreamObs : public Observer { public: StreamObs(const std::ostream& os) : os_(os) {} virtual void notify(const string& msg) { os << msg << std::endl; } }; class LoggerBetter { public: typedef vectorPrzykład użyciaObservers; LoggerBetter() {} void reg(Observer* o) { obs_.push_back(o); } int msg(const string& msg) const { for(Observers::const_iterator it = obs_.begin(); it != obs_.end(); ++it ) (*it)->notify(msg); } private: Observers obs_; };
LoggerBetter logger_better; FileObs obs_file1("file1"); FileObs obs_file2("file2"); MailObs obs_mail("address"); SteramObs obs_cerr(std::cerr); logger_better.reg(&obs_file1); logger_better.reg(&obs_file2); logger_better.reg(&obs_mail); logger_better.reg(&obs_cerr); logger_better.msg("test");