Observer Pattern - definiuje związek jeden do wielu pomiędzy obiektami. Dzięki temu gdy obiekt zmieni stan, obiekty zależnie zostaną powiadomione automatycznie.
Schemat ogólny UML:
Schemat składa się z 2 klas + interfejsu. Klasa Subject to klasa którą obserwujemy. Klasa Observer to klasa obserwująca klasę Subject. Dodatkowo każda klasa obserwująca implementuje interfejs IObserver zawierający jedną metodę: Update. W momencie zmiany jakiegoś atrybutu w klasie Subject, następuje wywołanie w pętli metody Update. Dzięki temu wszystkie obserwujące obiekty otrzymują aktualny stan klasy Subject. Jeśli ktoś przyjrzy się dokładnie, to z klasy Subject można wyodrębnić interfejs. Interfejs mógłby zawierać 3 podane metody: dodawania, usuwania i powiadamiania obiektów. Żeby jednak nie zaciemniać na początku samej idei, zatrzymamy się na takim schemacie.
Przykład:
Dosyć prosty przykład gdzie można zastosować opisywany wzorzec:
W momencie wpisywania tekstu w TexBox1 chcemy, aby reszta naszych texboxów także zawierała wpisywany przez nas tekst. Jest to najprostszy z możliwych przykładów, ale też być może najlepiej obrazujących wykorzystanie tego wzorca. SchematUML przykładu:
class Subject
{
private TextBox textBox;
private List listOfObservers;
public Subject(TextBox textBox)
{
this.textBox = textBox;
listOfObservers = new List();
textBox.TextChanged+=new EventHandler(textBox_TextChanged);
}
public void AddObserver(IObserver observer)
{
listOfObservers.Add(observer);
}
public void RemoveObserver(IObserver observer)
{
listOfObservers.Remove(observer);
}
private void Notify()
{
foreach (var item in listOfObservers)
{
item.Update(textBox.Text);
}
}
void textBox_TextChanged(object sender, EventArgs e)
{
Notify();
}
}
interface IObserver
{
void Update(string s);
}
class ConcreteClass : TextBox, IObserver
{
#region IObserver Members
public void Update(string s)
{
this.Text = s;
}
#endregion
}
public partial class Form1 : Form
{
private Subject subject;
public Form1()
{
InitializeComponent();
subject = new Subject(textBox1);
subject.AddObserver(concreteClass1);
subject.AddObserver(concreteClass2);
subject.AddObserver(concreteClass3);
subject.AddObserver(concreteClass4);
}
}
Na formatce oczywiście położyć musimy jednego TextBoxa oraz 4 obiekty typu ConcreteClass.
Gdzie wykorzystywać Obserwatora?
Wszędzie tam, gdzie potrzebujemy poinformować o zmianie danego obiektu innym obiektom. Można go wykorzystać podczas interakcji między formatkami oraz wszelkimi kontrolkami. Obrazowym przykładem użycia go jest zmiana w arkuszu kalkulacyjnym wykresu w zależności od wprowadzanych danych.
Brak komentarzy:
Prześlij komentarz