Beobachter (Entwurfsmuster)

Das Beobachter-Muster (englisch observer pattern, auch listener pattern) ist ein Entwurfsmuster aus dem Bereich der Softwareentwicklung. Es gehört zur Kategorie der Verhaltensmuster (engl. behavioral patterns) und dient der Weitergabe von Änderungen an einem Objekt an von diesem Objekt abhängige Strukturen.[1] Das Muster ist eines der sogenannten GoF-Muster (Gang of Four; siehe Viererbande).

Neben publish-subscribe (kurz pub/sub) erfährt das Beobachter-Muster mit dem Signal-Slot-Konzept eine weitere Ausprägung.

Verwendung

Allgemeine Anwendungssituationen

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

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 darstellenden 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.

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. Änderungen werden völlig unspezifisch zwischen dem beobachteten Objekt und jedem angemeldeten Beobachter ausgetauscht. Dieses braucht also die weitere Struktur dieser Komponenten nicht zu kennen. Die Beobachter implementieren ihrerseits eine (spezifische) Methode, um auf die Änderung zu reagieren.

Man unterscheidet drei verschiedene Arten, das Beobachter-Muster umzusetzen:[2]

Push Notification
Jedes Mal, wenn sich das beobachtete Objekt ändert, werden alle Beobachter benachrichtigt. Es werden jedoch keine Daten mitgeschickt, weshalb diese Form immer die gleiche Beobachter-Schnittstelle hat. Die Beobachter müssen nach Eintreffen der Nachricht Daten abholen.
Push-Update Notification
Jedes Mal, wenn sich das beobachtete Objekt ändert, werden alle Beobachter benachrichtigt. Zusätzlich leitet das beobachtete Objekt die Update-Daten, die die Änderungen beschreiben, an die Beobachter weiter.
Pull Notification
Der Beobachter fragt selbstständig nach dem Zustand des beobachteten Objekts.

UML-Diagramm

Klassendiagramm, das die am Entwurfsmuster beteiligten Rollen zeigt.

Das folgende Klassendiagramm zeigt die am Entwurfsmuster beteiligten Rollen. Das Subjekt kann mehrere Beobachter haben, die unterschiedlichen konkreten Klassen angehören können.

Akteure

Ein Subjekt (beobachtbares Objekt, auf Englisch publisher, also „Veröffentlicher“, genannt) hat eine Liste von Beobachtern, ohne deren konkrete Typen zu kennen. Es bietet eine Schnittstelle zur An- und Abmeldung von Beobachtern und eine Schnittstelle zur Benachrichtigung von Beobachtern über Änderungen an.

Ein konkretes Subjekt (konkretes, beobachtbares Objekt) speichert den relevanten Zustand und benachrichtigt alle Beobachter bei Zustandsänderungen über deren Aktualisierungsschnittstelle. Es verfügt über eine Schnittstelle zur Erfragung des aktuellen Zustands.

Die Beobachter (auf Englisch auch subscriber, also „Abonnent“, genannt) definieren eine Aktualisierungsschnittstelle.

Konkrete Beobachter verwalten die Referenz auf ein konkretes Subjekt, dessen Zustand sie beobachten und speichern und dessen Zustand konsistent ist. Sie implementieren eine Aktualisierungsschnittstelle unter Verwendung der Abfrageschnittstelle des konkreten Subjekts.

Vorteile

Subjekte und Beobachter können unabhängig variiert werden. Subjekt und Beobachter 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. Es werden auch Multicasts unterstützt.

Nachteile

Änderungen am Subjekt führen bei großer Beobachteranzahl zu hohen Änderungskosten. Außerdem 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.

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.

Ruft ein Beobachter während der Bearbeitung einer gemeldeten Änderung wiederum Änderungsmethoden des Subjektes auf, kann es zu Endlosschleifen kommen.

Typischerweise ist im Quellcode des Subjektes nicht erkennbar, welche Beobachter genau informiert werden. Es wird dadurch häufig schwer nachvollziehbar, welche Zustände das Programm bei einem Ereignis insgesamt durchläuft.

Beispiel in C++

Diese C++14 Implementierung basiert auf der vor C++98 Implementierung im Buch Entwurfsmuster.

#include <iostream>
#include <list>
#include <memory>

class Beobachter; // Beobachter Deklaration

class Subjekt {
public:
    Subjekt() :beobachtern() {}

    // kennt seine Beobachter. Eine beliebige Anzahl von Beobachtern kann ein Subjekt beobachten.

    void benachrichtige();

    // bietet eine Schnittstelle zum An- und Abmelden von Beobachtern.
    void meldeAn(Beobachter* beobachter) {
        beobachtern.push_front(beobachter);
    }

    void meldeAb(Beobachter* beobachter) {
        beobachtern.remove(beobachter);
    }

private:
    std::list<Beobachter*> beobachtern; // braucht Beobachter Deklaration
};

class Beobachter { // Beobachter Definition
public:
    // definiert eine Aktualisierungsschnittstelle für Objekte, die über Änderungen eines Subjekts benachrichtigt werden sollen.
    virtual void aktualisiere(Subjekt*) = 0;
    virtual ~Beobachter() = default;
};

void Subjekt::benachrichtige() {
    for (const auto& x:beobachtern)
        x->aktualisiere(this); // braucht Beobachter Definition
}

class KonkretesSubjekt: public Subjekt {
public:
    KonkretesSubjekt(): subjektZustand(0) {}

    int getZustand() {
        return subjektZustand;
    }

    void setZustand(int subjektZustand_) {
        subjektZustand = subjektZustand_;
        std::cout << "this=" << this << " subjektZustand=" << subjektZustand << '\n';
        // benachrichtigt seine Beobachter, wenn sich sein Zustand ändert.
        benachrichtige();
    }

private:
    // speichert den für KonkreterBeobachter relevanten Zustand.
    int subjektZustand;
};

class KonkreterBeobachter: public Beobachter {
public:
    KonkreterBeobachter(std::shared_ptr<KonkretesSubjekt> konkretesSubjekt_):
        beobachterZustand(0),
        konkretesSubjekt(konkretesSubjekt_.get()) {
        konkretesSubjekt->meldeAn(this);
    }

    KonkreterBeobachter(const KonkreterBeobachter&) = delete; // Dreierregel
    KonkreterBeobachter& operator=(const KonkreterBeobachter&) = delete;

    // implementiert die Aktualisierungsschnittstelle der Beobachterklasse, um seinen Zustand mit dem des Subjekts konsistent zu halten.
    void aktualisiere(Subjekt* subjekt) {
        if (subjekt == konkretesSubjekt) {
            beobachterZustand = konkretesSubjekt->getZustand();
            std::cout << "this=" << this << " beobachterZustand=" << beobachterZustand << '\n';
        }
    }

    virtual ~KonkreterBeobachter() {
        konkretesSubjekt->meldeAb(this);
    }

private:
    // speichert den Zustand, der mit dem des Subjekts in Einklang stehen soll.
    int beobachterZustand;
    // verwaltet eine Referenz auf ein KonkretesSubjekt.
    KonkretesSubjekt* konkretesSubjekt;
};

int main() {
    // Dynamischer Speicher (Heap). Smart pointers verhindern Memory Leaks.
    std::shared_ptr<KonkretesSubjekt> ks = std::make_shared<KonkretesSubjekt>();
    std::unique_ptr<KonkreterBeobachter> kb1 = std::make_unique<KonkreterBeobachter>(ks);
    std::unique_ptr<KonkreterBeobachter> kb2 = std::make_unique<KonkreterBeobachter>(ks);
    ks->setZustand(42);
}

Die Programmausgabe ist ähnlich zu:

this=0xad4e80 subjektZustand=42
this=0xad4ef0 beobachterZustand=42
this=0xad4eb0 beobachterZustand=42

Sonstiges

Bei der gerade durchgeführten Beobachtung 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 eventuell Synchronisationsmechanismen wie Sperren oder Warteschlangen zur Benachrichtigung der Beobachter erforderlich.)

Manche Programmiersprachen (wie beispielsweise Java) bieten eine Standard-Implementierung zum Beobachter-Muster an.[3] Allerdings führt eine solche Implementierung bei einer Programmiersprache, die keine multiple Vererbung von Klassen unterstützt, dazu, dass das Subjekt keine weiteren Klassen beerben kann, da es schon die Implementierung des Observer-Patterns erbt.

Verwandte Entwurfsmuster

Ein Vermittler kann zwischen Subjekten und Beobachtern vermitteln.

Wikibooks: Muster: Observer – Lern- und Lehrmaterialien

Einzelnachweise

  1. Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Entwurfsmuster. 5. Auflage. Addison-Wesley, 1996, ISBN 3-8273-1862-9, S. 287.
  2. Bernd Brügge, Allen H. Dutoit: Objektorientierte Softwaretechnik: mit UML, Entwurfsmustern und Java. 2., überarbeitete Auflage. Addison-Wesley Verlag, 2004, ISBN 3-8273-7082-5.
  3. Observer Interface Javadoc. docs.oracle.com, abgerufen am 3. Juni 2015.

Read other articles:

Cochem Lambang kebesaranLetak Cochem di Cochem-Zell Cochem Tampilkan peta JermanCochem Tampilkan peta Rheinland-PfalzKoordinat: 50°8′49″N 7°10′0″E / 50.14694°N 7.16667°E / 50.14694; 7.16667Koordinat: 50°8′49″N 7°10′0″E / 50.14694°N 7.16667°E / 50.14694; 7.16667NegaraJermanNegara bagianRheinland-PfalzKreisCochem-Zell Municipal assoc.Cochem Subdivisions4Pemerintahan • MayorWolfgang Lambertz (CDU)Luas •...

 

 

Willis LambNobel foundation, 1955Lahir(1913-07-12)12 Juli 1913Los Angeles, California, Amerika SerikatMeninggal15 Mei 2008(2008-05-15) (umur 94)Tucson, Arizona, Amerika SerikatKebangsaanAmerika SerikatAlmamaterUniversity of California, BerkeleyDikenal atasperpindahan LambPenghargaanNobel Fisika (1955)Karier ilmiahBidangFisikaInstitusiUniversity of ArizonaUniversity of OxfordYale UniversityColumbiaStanford UniversityPembimbing doktoralJulius Robert OppenheimerMahasiswa doktoralMarlan Scu...

 

 

20th-century total solar eclipse Solar eclipse of February 5, 1962MapType of eclipseNatureTotalGamma0.2107Magnitude1.043Maximum eclipseDuration248 s (4 min 8 s)Coordinates4°12′S 178°06′E / 4.2°S 178.1°E / -4.2; 178.1Max. width of band147 km (91 mi)Times (UTC)Greatest eclipse0:12:38ReferencesSaros130 (49 of 73)Catalog # (SE5000)9424 A total solar eclipse occurred on Monday[1], February 5, 1962. A solar eclipse occurs wh...

Cet article est une ébauche concernant une réalisatrice française et une écrivaine française. Vous pouvez partager vos connaissances en l’améliorant (comment ?) selon les conventions filmographiques. Pour plus d’informations, voyez le projet Cinéma. Pour les articles homonymes, voir Nina. Nina Companeez Nina Companeez au déjeuner des nommés des César du cinéma 2013. Données clés Nom de naissance Nina Hélène Kompaneitzeff Naissance 26 août 1937Boulogne-Billancourt (Se...

 

 

Place in Mount Lebanon Governorate, LebanonNiha نيحاNiha CityNihaLocation in LebanonCoordinates: 33°35′41″N 35°37′49″E / 33.59472°N 35.63028°E / 33.59472; 35.63028CountryLebanonGovernorateMount Lebanon GovernorateDistrictChouf DistrictElevation[1]335 ft (102 m)Population • Total6,500Time zoneUTC+2 (EET) • Summer (DST)+3 Niha (Arabic: نيحا [ˈniħa]) is a town in the Chouf which belongs to Mount Leban...

 

 

Canadian politician The HonourableJulian FantinoPC COM OOnt OMRIFantino in November 2012Member of Parliamentfor VaughanIn officeNovember 29, 2010 – August 4, 2015Preceded byMaurizio BevilacquaSucceeded byFrancesco SorbaraAssociate Minister of National DefenceIn officeJanuary 5, 2015 – November 4, 2015Prime MinisterStephen HarperPreceded byKerry-Lynne FindlaySucceeded byKent HehrIn officeMay 18, 2011 – July 4, 2012Prime MinisterStephen HarperPreceded by...

Farid AzarkanAzarkan pada 2017 Pemimpin Denk dalam Dewan Perwakilan RakyatMasa jabatan21 Maret 2020 – 2 Agustus 2023 PendahuluTunahan KuzuPenggantiStephan van BaarleAnggota Dewan Perwakilan RakyatMasa jabatan23 Maret 2017 – 6 Desember 2023 Informasi pribadiLahir16 Oktober 1971 (umur 52)Tafersit, MarokoKebangsaanMarokoBelandaPartai politikDenkTempat tinggalCulemborg, BelandaAlma materChristelijke Hogeschool Nederland [nl] (BBA)Vrije Universiteit Amsterda...

 

 

Governorate of Yemen Governorate in Hadramout Region, YemenShabwah محافظة شَبْوَةGovernorateCountry YemenRegion Hadramout RegionCapital cityAtaqGovernment • GovernorMohammed Saleh bin Adeow [1][2]Area • Total47,728 km2 (18,428 sq mi)Population (2011)[3] • Total668,000 • Density14/km2 (36/sq mi) Shabwah (Arabic: شَبْوَة, romanized: Šabwa) is a governorate (provin...

 

 

Alessandro Budel Nazionalità  Italia Altezza 183 cm Peso 82 kg Calcio Ruolo Allenatore (ex centrocampista) Termine carriera 2017 Carriera Giovanili 1998-2000 Milan Squadre di club1 2000-2002→  Spezia46 (1)[1]2002-2003→  Triestina33 (0)2003-2004→  Lecce7 (0)2004→  Genoa20 (0)2004-2005→  Parma10 (0)2005-2008 Cagliari83 (1)2008 Empoli19 (2)2008-2010 Parma36 (3)2010-2011 Brescia32 (1)[2]2011→  Torino16 (0)20...

Province of Italy Province in Calabria, ItalyProvince of CosenzaProvincePalazzo del Governo, the provincial seat FlagCoat of armsMap highlighting the location of the province of Cosenza in ItalyCountry ItalyRegionCalabriaCapital(s)CosenzaComuni150Government • PresidentFranco Antonio IacucciArea • Total6,710 km2 (2,590 sq mi)Population (30 April 2017) • Total710,189 • Density110/km2 (270/sq mi)GDP[1] •...

 

 

Минерва Минерва Джузеппе Вольпини во Дворцовом парке Нимфенбург, Мюнхен. Мифология римская Сфера влияния ремесленник, торговля[d], поэт и учитель Пол женский Отец Юпитер Мать Метида В иных культурах Афина, Senuna[d], Belisama[d] и Sulis[d]  Медиафайлы на Викиск...

 

 

María Juliana Ruiz Sandoval Ibu Negara KolombiaAssummed Role7 Agustus 2018 – 7 Agustus 2022PresidenIván Duque MárquezPendahuluMaría Clemencia SantosPenggantiVerónica Alcocer Informasi pribadiLahirMaría Juliana Ruiz Sandoval23 Mei 1978 (umur 45)Bogotá, KolombiaKewarganegaraanKolombiaSuami/istriIván Duque MárquezAnak3Sunting kotak info • L • B María Juliana Ruiz Sandoval (lahir 23 Mei 1978)[1] adalah Ibu Negara Republik Kolombia. Ia menikah dengan...

内華達州 美國联邦州State of Nevada 州旗州徽綽號:產銀之州、起戰之州地图中高亮部分为内華達州坐标:35°N-42°N, 114°W-120°W国家 美國建州前內華達领地加入聯邦1864年10月31日(第36个加入联邦)首府卡森城最大城市拉斯维加斯政府 • 州长(英语:List of Governors of {{{Name}}}]]) • 副州长(英语:List of lieutenant governors of {{{Name}}}]])喬·隆巴爾多(R斯塔...

 

 

此條目之中立性有争议。其內容、語調可能帶有明顯的個人觀點或地方色彩。 (2011年6月)加上此模板的編輯者需在討論頁說明此文中立性有爭議的原因,以便讓各編輯者討論和改善。在編輯之前請務必察看讨论页。 格奥尔基·季米特洛夫保加利亚共产党中央委员会总书记任期1948年8月—1949年7月2日前任自己(第一书记)继任维尔科·契尔文科夫保加利亚共产党中央委员会第一�...

 

 

Chinatowns in the AmericasChinatown, Manhattan, the highest concentration of Chinese people outside Asia.[1][2][3]Chinese唐人街Literal meaningChinese StreetTranscriptionsStandard MandarinHanyu PinyinTángrénjiēWuRomanizationDaon平 nin平 ka平Yue: CantoneseYale RomanizationTòhngyàhngāaiJyutpingTong2 jan2 gaai1Southern MinHokkien POJTông-jîn-keEastern MinFuzhou BUCTòng-ìng-kĕAlternative Chinese nameTraditional Chinese中國城Simplified Chinese中国...

本文或本章節是關於未來的公共运输建設或計划。未有可靠来源的臆測內容可能會被移除,現時內容可能與竣工情況有所出入。 此条目讲述中国大陆處於施工或详细规划阶段的工程。设计阶段的資訊,或許与竣工后情況有所出入。无可靠来源供查证的猜测会被移除。 设想中的三条路线方案[1]。 臺灣海峽隧道或臺湾海峡橋隧(英語:Taiwan Strait Tunnel Project)是一项工程�...

 

 

1994 video gameSub-TerraniaNorth American coverDeveloper(s)ZyrinxPublisher(s)SegaProducer(s)Tony VanProgrammer(s)David GuldbrandsenKarsten L. HvidbergJens Bo AlbretsenThomas RisagerArtist(s)Jesper Vorsholt JørgensenMikael BalleKarsten LundComposer(s)Jesper KydPlatform(s)Mega Drive/GenesisReleaseNA: March 1994[2]EU: April 1994[1]Genre(s)Multidirectional shooterMode(s)Single-player Sub-Terrania is a 1994 multidirectional shooter developed by Danish studio Zyrinx and published b...

 

 

Artikel ini bukan mengenai bugang. Wikispecies mempunyai informasi mengenai Bagang. Bagang Chelmon rostratus Status konservasiRisiko rendahIUCN165659 TaksonomiKerajaanAnimaliaFilumChordataKelasActinopteriOrdoChaetodontiformesFamiliChaetodontidaeGenusChelmonSpesiesChelmon rostratus Linnaeus, 1758 Bagang,[1][2] bale tandjoing[3][4] atau pipit[3] (Chelmon rostratus) adalah ikan laut yang hidup di perairan karang tropis dengan kedalaman 25 m, ukuran panjang...

Presiding judge of the Supreme Court of Pakistan Chief Justice of Pakistanمنصفِ اعظم پاکستانMunsif-e-Āzam Pākistānقاضیُ الْقُضاۃEmblem of the SCPIncumbentQazi Faez Isasince 17 September 2023Supreme Court of PakistanStyleThe Honorable (formal)Your Lordship (within court)Mr. Chief Justice(informal)StatusChief justiceSeatSupreme Court Building, Red Zone, IslamabadNominatorPrime Minister of PakistanAppointerPresident of PakistanTerm lengthVariable (until the a...

 

 

  لمعانٍ أخرى، طالع الحيرة (توضيح). الحيرة   الاسم الرسمي الحيرة الإحداثيات 25°22′53″N 55°24′11″E / 25.381388888889°N 55.403055555556°E / 25.381388888889; 55.403055555556   تقسيم إداري  البلد الإمارات العربية المتحدة  إمارة الشارقة خصائص جغرافية ارتفاع 0 م (3 قدم) معلومات أخرى م...