Observer Pattern
Observer pattern kan in C# op twee manieren gebruikt worden:
- Object die een lijst met objecten bijhoud en bij een event een bericht stuurt naar die lijst met objecten.
- Object met een delegate en een event, objecten kunnen abboneren op dat event.
Voorbeeld 1:
using System; using System.Collections; namespace Wikipedia.Patterns.Observer { // IObserver --> interface for the observer public interface IObserver { // called by the subject to update the observer of any change // The method parameters can be modified to fit certain criteria void Update(string message); } public class Subject { // use array list implementation for collection of observers private ArrayList observers; // constructor public Subject() { observers = new ArrayList(); } public void Register(IObserver observer) { // if list does not contain observer, add if (!observers.Contains(observer)) { observers.Add(observer); } } public void Unregister(IObserver observer) { // if observer is in the list, remove if (observers.Contains(observer)) { observers.Remove(observer); } } public void Notify(string message) { // call update method for every observer foreach (IObserver observer in observers) { observer.Update(message); } } } // Observer1 --> Implements the IObserver public class Observer1 : IObserver { public void Update(string message) { Console.WriteLine("Observer1:" + message); } } // Observer2 --> Implements the IObserver public class Observer2 : IObserver { public void Update(string message) { Console.WriteLine("Observer2:" + message); } } // Test class public class ObserverTester { [STAThread] public static void Main() { Subject mySubject = new Subject(); IObserver myObserver1 = new Observer1(); IObserver myObserver2 = new Observer2(); // register observers mySubject.Register(myObserver1); mySubject.Register(myObserver2); mySubject.Notify("message 1"); mySubject.Notify("message 2"); } } }
Voorbeeld 2:
using System; // First, declare a delegate type that will be used to fire events. // This is the same delegate as System.EventHandler. // This delegate serves as the abstract observer. // It does not provide the implementation, but merely the contract. public delegate void EventHandler(object sender, EventArgs e); // Next, declare a published event. This serves as the concrete subject. // Note that the abstract subject is handled implicitly by the runtime. public class Button { // The EventHandler contract is part of the event declaration. public event EventHandler Clicked; // By convention, .NET events are fired from descendant classes by a virtual method, // allowing descendant classes to handle the event invocation without subscribing // to the event itself. protected virtual void OnClicked(EventArgs e) { if (Clicked != null) Clicked(this, e); // implicitly calls all observers/subscribers } } // Then in an observing class, you are able to attach and detach from the events: public class Window { private Button okButton; public Window() { okButton = new Button(); // This is an attach function. Detaching is accomplished with -=. // Note that it is invalid to use the assignment operator - events are multicast // and can have multiple observers. okButton.Clicked += new EventHandler(okButton_Clicked); } private void okButton_Clicked(object sender, EventArgs e) { // This method is called when Clicked(this, e) is called within the Button class // unless it has been detached. } }