Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Das Observerpattern

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: [ 1 ] [ 2 ] [ 3 ] > 4 <
030
01.09.2006, 09:45 Uhr
(un)wissender
Niveauwart



Zitat von Spacelord:

Und wenn du doch ohnehin ne Observerklasse schreiben musst um mehreren(eigentlich unterschiedlichen) Klassen die Möglichkeit zu geben sich beim Subjekt anzumelden dann kannst du dir den ganzen Templatekram auch sparen.



Sehe ich nicht so. Ansonsten müsste ich für alle eine Basisklasse vorgeben, dass wäre überhaupt nicht gut.
Und, wie gesagt, wenn du keine Basisklasse haben willst, geht boost::any immer.
Anonsten ist das Observerpattern nunmal so.
Wenn du eine bessere Idee zur Umsetzung hast, dann zeig das doch mal.
--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 01.09.2006 um 09:46 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
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.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
032
01.09.2006, 17:16 Uhr
(un)wissender
Niveauwart


?
Das geht bei meiner Lösung genauso. Abgeleitet und dann rufen die update-Methoden deine Sachen auf. Fertig.
Ich kenne das Observerpattern sehr genau und so funzt es. Ansonsten, ao hat ja den Wikipedialink gepostet.
Es wird halt immer eine Methode(n-Signatur) für alle Observer aufgerufen. Wie willst du das ändern? Unterschiedliche Methodenpointer registrieren? Mit Wrappern in einem heterogenen Container. Woher weißt du welche Signaturen die haben? Willst du die wieder vorgeben? Nichts ist gewonnen.
Ich behaupte, dass das was dir so vorschwebt weder das Observerpattern ist noch realisierbar.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
033
01.09.2006, 17:47 Uhr
Spacelord
Hoffnungsloser Fall


Dann reden wir also doch aneinander vorbei.
Mir schwebt ansonsten garnichts vor!
Das was du mir jetzt vorwirfst vorzuhaben ist genau dass was ich die ganze Zeit versuche dir unterzujubeln .
So wie es da oben ist läuft es und ohne die Basisklasse mit der gemeinsamen Schnittstelle geht es halt nicht.
Aber warum beharrst du dann die ganze Zeit darauf dass du keine gemeinsame Oberklasse haben möchtest weil das schlecht ist???

Zitat von (un)wissender:

Ansonsten müsste ich für alle eine Basisklasse vorgeben, dass wäre überhaupt nicht gut.
...
Aus diesem Grund gibt es keine Observerschnittstelle....
....



Gruss Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
034
02.09.2006, 12:56 Uhr
(un)wissender
Niveauwart



Zitat von Spacelord:

Aber warum beharrst du dann die ganze Zeit darauf dass du keine gemeinsame Oberklasse haben möchtest weil das schlecht ist???



Nein, ich möchte keine bibliotheksseitig vorgeben, dass ist etwas anderes.

--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] [ 2 ] [ 3 ] > 4 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: