Das Observer Pattern – Wenn Code kommuniziert…

In Verbindung mit MVVM sollen der Vollständigkeit halber die Arbeiter hinter den Kulissen etwas erläutert werden, um einfach auch zu zeigen, was dem Entwickler durch das .NET Framework alles an Arbeit abgenommen wird. – Nun zum Thema

SnapFinalApplication

Wer sich an das oben gezeigte Bild aus dem MVVM Beispielen erinnert, ist nun sprichwörtlich alles Bestens. Leider wird es dies immer der Fall sein. Wenn sich nun der Status des hier nur bildlich vorgestellten Servers ändern sollte, würde dies in der View nie dargestellt werden, weil sie über Änderungen im Model vom View Model bis jetzt nicht informiert wird. Darum kümmert sich eine Implementierung des Observer Patterns in .NET.

Mit Hilfe des Observer Patterns können Änderungen eines einzelnen Objektes allen dazu in Beziehung stehenden Objekten bekannt gemacht werden. Dabei wird von Subject und Obeservern (Beobachtern) gesprochen. Ein Subject kann mehrere Observer besitzen. Sobald eine Änderung im Subject auftritt, können alle Observer benachrichtigt werden und darauf reagieren.

ObserverPatternDiagram

Vereinfachtes Schema des Observer Patterns

Bei der Übertragung des Schemas auf das MVVM ergibt sich für die View die Rolle des Observers. Sobald im Datenmodell Änderungen auftreten, soll die Benutzeroberfläche entsprechend informiert werden. Das View Model muss diese Änderungen als Subject publizieren.

Ab jetzt wird es für den Entwickler sehr einfach. Die Implementierung des Observer Patterns findet nicht statt, da es von dem .NET Framework geliefert wird. Wenn das View Model das Interface INotifyPropertyChanged implementiert, registriert sich die View automatisch als Observer an dem View Model.

Das nachstehende Beispiel knüpft an das Projekt aus den vorangegangenen Kapiteln an und demonstriert den Einsatz von INotifyPropertyChanged.

[sourcecode language=”csharp”]
using System.ComponentModel;

namespace T_SimpleDataBinding
{
public class StatusMessageViewModel : INotifyPropertyChanged
{
private string _statusMessage;
public string StatusMessage
{
get { return _statusMessage; }
set
{
_statusMessage = value;
OnPropertyChanged("StatusMessage");
}
}

public void ModelStatusRequestCompleted
(object sender, StatusEventArgs e)
{
StatusMessage = e.Result;
}

public event PropertyChangedEventHandler PropertyChanged;

private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged
(this, new PropertyChangedEventArgs(property));
}
}
}
}
[/sourcecode]

Beginnen wir in Zeile 05. Das Implementieren von INotifyPropertyChanged erzwingt die Deklaration des eines Events, z u sehen in Zeile 24. Dieses Event wird automatisch von der View abonniert. Nun muss dieses Event immer dann gerufen werden, wenn sich eine Eigenschaft im View Model ändert. Dafür wurde im set der StatusMessage Property in Zeile 14 ein Methodenaufruf gesetzt. Das heißt, immer wenn der Eigenschaft ein Wert zugewiesen wird, wird diese Methode gerufen. Die Methode macht nichts anderes, als zu prüfen, ob es einen Abonnenten für das Event gibt. Wenn das der Fall ist wird das PropertyChanged Event „gefeuert“. Dabei wird der Name der geänderten Eigenschaft in der string – Variable property übergeben. So kann die View entscheiden, welches Oberflächenelement aktualisieren muss.

Hinweis: Damit dieser Ansatz in der Umsetzung problemlos funktioniert, sollten eindeutige Bezeichnungen für die Eigenschaften vergeben werden. Bei gleicher Namensgebung werden mehrere Benutzerelemente fälschlicherweise aktualisiert.

Neben dem Interface INotifyPropertyChanged gibt es noch weitere Implementierungshilfen für das Observer Pattern, die als zusätzliche Information hier genannt werden.

Mit Hilfe des INotifyCollectionChanged können Observer über die Änderungen einer ganzen Liste von Eigenschaften informiert werden. Die Klasse ObservableCollection<T> implementiert diese Schnittstelle bereits. In einem späteren Szenario wird deren Einsatz demonstriert.

Gregor

Gregor Woiwode ist Angestellter der heco GmbH, wo er als Sofwareentwickler und Trainer tätig ist. Sein Fokus liegt in der Erstellung von Webportalen mit dem .NET- und Angular-Framework. Von 2007 bis 2010 studierte er Telekommunikationsinformatik an der Hochschule für Telekommunikation in Leipzig und schloss den Studiengang als Bachelor of Engineering ab. Derzeit studiert er im Studiengang Wirtschaftsinformatik um die Auszeichnung Master of Science zu erhalten.

What do you think? Please leave a Comment below!