031
01.09.2006, 17:04 Uhr
Spacelord
Hoffnungsloser Fall
|
Zitat von (un)wissender: |
Sehe ich nicht so. Ansonsten müsste ich für alle eine Basisklasse vorgeben, dass wäre überhaupt nicht gut.
|
Vielleicht reden wir ja über unterschiedliche Observer, aber bei dem Observerpattern von dem ich rede ist gerade diese Basisklasse der "Trick" bei der Sache...sozusagen das Zitronencremebällchen das benötigt wird um die Zielsetzung zu erreichen. Zu den elementaren Zielen des Observerpatterns gehört es nämlich dass der Beobachtete den konkreten Typ des Beobachters nicht kennen muss. Hier ist mal ne Minimalimplementierung des Observerpatterns,dass sich so verhält wie ich es von dem Pattern erwarte. observer.h
C++: |
#ifndef __OBSERVER_H #define __OBSERVER_H
#include <list> #include <algorithm>
class observer { public: virtual void update()=0; };
class observable { public: void notify() { std::list<observer*>::iterator it = _observers.begin(); while(it != _observers.end()) { (*it)->update(); ++it; } } void register_observer(observer* new_observer) { _observers.push_back(new_observer); } void unregister_observer(observer* _obs) { std::list<observer*>::iterator pos = std::find(_observers.begin(),_observers.end(),_obs); if(pos != _observers.end()) _observers.erase(pos); } private: std::list<observer*> _observers; };
#endif
|
main.cpp
C++: |
#include "observer.h" #include <iostream>
using namespace std;
class document:public observable { public: document(int _value=0):value(_value){} int get_value()const{return value;} void set_value(int i) { value=i; this->notify(); } private: int value; };
class view:public observer { public: view(document& _doc):doc(_doc){} void update() { this->show(); } int show() { int val = doc.get_value(); cout<<"View:Der neue Werte des Dokuments ist: "<<val<<'\n';
return val; } private: document& doc; };
class db_updater:public observer { public: db_updater(document& _doc):doc(_doc){} void update() { if(this->set_db_value(doc.get_value())) cout<<"......hat geklappt"<<'\n'; } bool set_db_value(int i) { cout<<"DB-Updater:Ich aktualisiere die Datenbank mit dem Wert: "<<i; //rueckgabewert wäre eventuell bei nem echten Update von Interesse //hier einfach immer true; return true; } private: document& doc; };
int main() { document d(8); view vw(d); db_updater dbu(d);
d.register_observer(&vw); d.register_observer(&dbu); d.set_value(12);
return 0; }
|
Wie würde denn genau dieses Verhalten mit deinem Observercode aussehen? Von mir aus kannst du auch boost::any benutzen.Hab damit selber noch nichts gemacht aber ich bin gespannt wie du an dieser Stelle
C++: |
std::for_each(_observer.begin(), _observer.end(), u);
|
ohne weitere Änderungen for_each dazu bringen möchtest entweder view::show oder db_updater::set_db_value aufzurufen.Geht bestimmt auch irgendwie mit boost::any,aber ob das wirklich der Weg ist? Ich wüsste nicht warum ich mit so nem windigen Multityp arbeiten sollte nur um die Basisklasse eines Patterns zu sparen.
Zitat von (un)wissender: |
Anonsten ist das Observerpattern nunmal so.
|
Dann schau dir nochmal genau das UML Diagramm und vor allem die Zielsetzung des Patterns an.
Gruss Spacelord -- .....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes. |