Static Wikipedia February 2008 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Web Analytics
Cookie Policy Terms and Conditions Beobachter (Entwurfsmuster) - Wikipedia

Beobachter (Entwurfsmuster)

aus Wikipedia, der freien Enzyklopädie

Der Beobachter (englisch Observer) ist ein Entwurfsmuster aus dem Bereich der Softwareentwicklung und gehört zu der Kategorie der Verhaltensmuster (Behavioural Patterns). Es dient zur Weitergabe von Änderungen an einem Objekt an von diesem Objekt abhängige Strukturen. Das Muster ist eines der sogenannten GoF-Muster (siehe Viererbande).

Dieses Entwurfsmuster ist auch unter dem Namen publish-subscribe bekannt, frei übersetzt „veröffentlichen und abonnieren“.

Inhaltsverzeichnis

[Bearbeiten] Verwendung

[Bearbeiten] Anwendungsbeispiel

Eine oder auch mehrere Komponenten stellen den Zustand eines Objektes grafisch dar. Sie kennen die gesamte Schnittstelle dieses Objektes. Ändert sich der Zustand des Objektes, müssen die Komponenten darüber informiert werden. Andererseits soll das Objekt aber von den Komponenten unabhängig bleiben - ihre Schnittstelle also nicht kennen.

  • Beispiel: Messergebnisse werden gleichzeitig in einem Balkendiagramm, einem Liniendiagramm und einer Tabelle dargestellt. Messwerte ändern sich permanent. Die Komponenten der Diagramme sollen diese Änderungen permanent darstellen, das gemessene Objekt soll dabei aber keine Kenntnis über die Struktur dieser Komponenten besitzen.

[Bearbeiten] Lösung

Das beobachtete Objekt bietet einen Mechanismus, um Beobachter an- und abzumelden und diese über Änderungen zu informieren. Es kennt alle seine Beobachter nur über die (überschaubare) Schnittstelle Beobachter. Es meldet jede Änderung völlig unspezifisch an jeden angemeldeten Beobachter, braucht also die weitere Struktur dieser Komponenten nicht zu kennen.

Die Beobachter implementieren ihrerseits eine (spezifische) Methode, um auf die Änderung zu reagieren. In der Regel werden die für eine Komponente relevanten Teile des Zustands abgefragt.

[Bearbeiten] Allgemeine Anwendungssituationen

Allgemein finden Beobachter Anwendung, wenn

  • eine Abstraktion mehrere Aspekte hat, die von einem anderen Aspekt derselben Abstraktion abhängen,
  • die Änderung eines Objekts Änderungen an anderen Objekten nach sich zieht oder
  • ein Objekt andere Objekte benachrichtigen soll, ohne diese im Detail zu kennen.

[Bearbeiten] UML-Diagramm

Bild:Beobachter.png

[Bearbeiten] Akteure

  • Subjekt (Beobachtbares Objekt, auch Publisher, also „Veröffentlicher“, genannt)
    • kennt Liste von Beobachtern, aber keine konkreten Beobachter
    • bietet Schnittstelle zur An- und Abmeldung von Beobachtern
    • bietet Schnittstelle zur Benachrichtigung von Beobachtern über Änderungen
  • KonkretesSubjekt (Konkretes, beobachtbares Objekt)
    • speichert relevanten Zustand
    • benachrichtigt alle Beobachter bei Zustandsänderungen über deren Aktualisierungsschnittstelle
    • Schnittstelle zur Erfragung des aktuellen Zustands
  • Beobachter (auch Subscriber, also „Abonnent“, genannt)
    • definiert Aktualisierungsschnittstelle
  • KonkreterBeobachter
    • verwaltet Referenz auf ein konkretes Subjekt, dessen Zustand es beobachtet
    • speichert dessen Zustand konsistent
    • implementiert Aktualisierungsschnittstelle unter Verwendung der Abfrageschnittstelle des konkreten Subjekts

[Bearbeiten] Vorteile

  • Subjekte und Beobachter können unabhängig variiert werden.
  • Subjekt und Benutzer sind auf abstrakte und minimale Art lose gekoppelt. Das beobachtete Objekt braucht keine Kenntnis über die Struktur seiner Beobachter zu besitzen, sondern kennt diese nur über die Beobachter-Schnittstelle.
  • Ein abhängiges Objekt erhält die Änderungen automatisch.
  • Multicasts werden unterstützt.

[Bearbeiten] Nachteile

  • Änderungen am Objekt führen bei großer Beobachteranzahl zu hohen Änderungskosten. Einerseits informiert das Subjekt jeden Beobachter, auch wenn dieser die Änderungsinformation nicht benötigt. Zusätzlich können die Änderungen weitere Änderungen nach sich ziehen und so einen unerwartet hohen Aufwand haben.
  • Ruft ein Beobachter während der Bearbeitung einer gemeldeten Änderung wiederum Änderungsmethoden des Subjektes auf, kann es zu Endlosschleifen kommen.
  • Der Mechanismus liefert keine Information darüber, was sich geändert hat. Die daraus resultierende Unabhängigkeit der Komponenten kann sich allerdings auch als Vorteil herausstellen.
  • Bei der gerade durchgeführten Observierung eines Objektzustands kann es notwendig sein, einen konsistenten Subjektzustand zu garantieren. Dies kann durch synchrone Aufrufe der Notifizierungsmethode des Beobachters sichergestellt werden. In einem Multithreading System sind evtl. Lockingmechanismen oder Threads mit queuing zur Beobachter-Notifizierung erforderlich.

[Bearbeiten] Beispiele

Implementierung in C++

class CObserver
{
public:
  virtual void NotifyStateChange( void ) = 0 ;
} ;

class CObserverSubject
{
private:
  typedef CObserver tObserver ;
  typedef std::deque< tObserver* > tOBSERVERS ;
  tOBSERVERS Observers ;

public:
  bool AddObserver( tObserver* Observer )
  {
    tOBSERVERS::const_iterator foundObserver =
        std::find( this->Observers.begin(), this->Observers.end(), Observer ) ;
    if( foundObserver == this->Observers.end() )
    {
      this->Observers.push_back( Observer ) ;
      return true ;
    }
    else
    {
      return false ;
    }
  }

  bool RemoveObserver( tObserver* Observer )
  {
    tOBSERVERS::iterator foundObserver =
        std::find( this->Observers.begin(), this->Observers.end(), Observers ) ;
    if( foundObserver != this->Observers.end() )
    {
      this->Observers.erase( foundObserver ) ;
      return true ;
    }
    else
    {
      return false ;
    }
  }

  void NotifiyStateChange()
  {
    tOBSERVERS::const_iterator allObservers = this->Observers.begin() ;
    while( allObservers != this->Observers.end() )
    {
      ( *allObservers )->NotifyStateChange() ;
        allObservers++;
    }
  }
} ;


Weiteres Beispiel in C++

#include <list>
#include <string>
#include <iostream>
#include <sstream>
#include <algorithm>

/************************** Subjekt und Beobachter ***********************************/

class Subject;

struct Observer
{
  virtual void update( Subject* ) = 0;
};

class Subject
{
public:
  void attach( Observer* );
  void detach( Observer* );
  void notify();
private:
  std::list<Observer*> observers_;
};

void Subject::attach( Observer* o ) //MeldeAn
{
  observers_.push_back(o);
}

void Subject::detach( Observer* o ) //MeldeAb
{
  observers_.erase(
    std::remove_if(observers_.begin(), observers_.end(), std::bind2nd(std::equal_to<Observer *>(), o)),
    observers_.end());
}

void Subject::notify() //Benachrichtige
{
  std::for_each(observers_.begin(), observers_.end(), std::bind2nd(std::mem_fun(&Observer::update), this));
}

/************************** Konkretes Subjekt ***********************************/

class MailServer : public Subject
{
public:
  MailServer( std::string name ): name_(name){}
  void neuerNewsletter() { notify(); }
  std::string getName()  const {return name_;}
private:
  const std::string name_;
};

/************************** Konkreter Beobachter ***********************************/

class EmailKonto: public Observer
{
public:
  EmailKonto( std::string name, MailServer* );
  ~EmailKonto();
  void update( Subject* );
  std::string getName()    const {return name_;}
  MailServer* getSubject() const {return subject_;}
private:
  const std::string name_;
  MailServer* subject_;
};

EmailKonto::EmailKonto( std::string name, MailServer* s ) : name_(name), subject_(s)
{
  subject_->attach(this);
}

EmailKonto::~EmailKonto () { subject_->detach(this); }

void EmailKonto::update( Subject* s ) //Aktualisiere
{
  if( s == subject_ )
      std::cout << "Hallo Herr Nr. " << getName() << ", ein neuer Newsletter von "
      << subject_->getName()<< " ist erschienen." << std::endl;
}


/************************** Hauptprogramm ***********************************/

int main()
{
  MailServer s("HenkesSoft3000");           //Subjekt "MailServer"
 
  const int N = 5;

  EmailKonto** pMK = new EmailKonto*[N];


  for(int i=0; i<N; ++i)
  {
    std::ostringstream n;
    n << i;
    pMK[i] = new EmailKonto(n.str(), &s);   //Mailkonten melden sich an
  }

  s.neuerNewsletter();
  
  for(int i=0; i<(N-2); ++i)
  {
    pMK[i]->getSubject()->detach(pMK[i]);     //Zwei Mailkonten melden sich ab
  }

  s.neuerNewsletter();
  
  delete [] pMK;
}

[Bearbeiten] Listener und Events in Java

Java bietet fertige Observer und Observableklassen an, die der Entwickler verwenden kann.

Die Nachteile des Entwurfsmusters entfernt Java, indem es das Beobachterkonzept durch Listener und Events ersetzt. Interessiert sich eine Klasse für eine andere, implementiert sie deren Listener-Interface und meldet sich beim Subjekt an. Ändert sich das Subjekt, informiert es seine Beobachter durch den Aufruf der Listenerschnittstelle, die die Änderung beschreibt.

[Bearbeiten] Verwandte Entwurfsmuster

  • Ein Vermittler kann zwischen Subjekten und Beobachtern vermitteln.

[Bearbeiten] Siehe auch

b:
Wikibooks
Wikibooks: Muster: Observer – Lern- und Lehrmaterialien
Static Wikipedia 2008 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -

Static Wikipedia 2007 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -

Static Wikipedia 2006 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu