Definition
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
The classes and objects participating in this pattern are:
- Subject (Stock)
- knows its observers. Any number of Observer objects may observe a subject
- provides an interface for attaching and detaching Observer objects.
- ConcreteSubject (IBM)
- stores state of interest to ConcreteObserver
- sends a notification to its observers when its state changes
- Observer (IInvestor)
- defines an updating interface for objects that should be notified of changes in a subject.
- ConcreteObserver (Investor)
- maintains a reference to a ConcreteSubject object
- stores state that should stay consistent with the subject's
- implements the Observer updating interface to keep its state consistent with the subject's
Structural code in C#
This structural code demonstrates the Observer pattern in which registered objects are notified of and updated with a state change.
-
-
using System.Collections.Generic;
-
namespace DoFactory.GangOfFour.Observer.Structural
-
-
/// MainApp startup class for Structural
/// Observer Design Pattern.
-
-
-
-
/// Entry point into console application.
-
-
-
// Configure Observer pattern
ConcreteSubject s = new ConcreteSubject();
-
s.Attach(new ConcreteObserver(s, "X"));
s.Attach(new ConcreteObserver(s, "Y"));
s.Attach(new ConcreteObserver(s, "Z"));
-
// Change subject and notify observers
-
-
-
-
-
-
-
-
-
/// The 'Subject' abstract class
-
-
-
private List<Observer> _observers = new List<Observer>();
-
public void Attach(Observer observer)
-
_observers.Add(observer);
-
-
public void Detach(Observer observer)
-
_observers.Remove(observer);
-
-
-
-
foreach (Observer o in _observers)
-
-
-
-
-
-
-
/// The 'ConcreteSubject' class
-
class ConcreteSubject : Subject
-
private string _subjectState;
-
// Gets or sets subject state
public string SubjectState
-
get { return _subjectState; }
set { _subjectState = value; }
-
-
-
-
/// The 'Observer' abstract class
-
-
-
public abstract void Update();
-
-
-
/// The 'ConcreteObserver' class
-
class ConcreteObserver : Observer
-
-
private string _observerState;
private ConcreteSubject _subject;
-
-
-
ConcreteSubject subject, string name)
-
-
-
-
-
public override void Update()
-
_observerState = _subject.SubjectState;
Console.WriteLine("Observer {0}'s new state is {1}",
-
-
-
-
public ConcreteSubject Subject
-
-
set { _subject = value; }
-
-
-
-
-
-
-
Output
Observer X's new state is ABC
Observer Y's new state is ABC
Observer Z's new state is ABC
Real-world code in C#
This real-world code demonstrates the Observer pattern in which registered investors are notified every time a stock changes value.
-
-
using System.Collections.Generic;
-
namespace DoFactory.GangOfFour.Observer.RealWorld
-
-
/// MainApp startup class for Real-World
/// Observer Design Pattern.
-
-
-
-
/// Entry point into console application.
-
-
-
// Create IBM stock and attach investors
IBM ibm = new IBM("IBM", 120.00);
ibm.Attach(new Investor("Sorros"));
ibm.Attach(new Investor("Berkshire"));
-
// Fluctuating prices will notify investors
-
-
-
-
-
-
-
-
-
-
-
/// The 'Subject' abstract class
-
-
-
-
-
private List<IInvestor> _investors = new List<IInvestor>();
-
-
public Stock(string symbol, double price)
-
-
-
-
-
public void Attach(IInvestor investor)
-
_investors.Add(investor);
-
-
public void Detach(IInvestor investor)
-
_investors.Remove(investor);
-
-
-
-
foreach (IInvestor investor in _investors)
-
-
-
-
-
-
-
// Gets or sets the price
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/// The 'ConcreteSubject' class
-
-
-
-
public IBM(string symbol, double price)
-
-
-
-
-
-
/// The 'Observer' interface
-
-
-
void Update(Stock stock);
-
-
-
/// The 'ConcreteObserver' class
-
class Investor : IInvestor
-
-
-
-
-
public Investor(string name)
-
-
-
-
public void Update(Stock stock)
-
Console.WriteLine("Notified {0} of {1}'s " +
"change to {2:C}", _name, stock.Symbol, stock.Price);
-
-
// Gets or sets the stock
-
-
-
-
-
-
-
-
-
-
Output
Notified Sorros of IBM's change to $120.10
Notified Berkshire of IBM's change to $120.10
Notified Sorros of IBM's change to $121.00
Notified Berkshire of IBM's change to $121.00
Notified Sorros of IBM's change to $120.50
Notified Berkshire of IBM's change to $120.50
Notified Sorros of IBM's change to $120.75
Notified Berkshire of IBM's change to $120.75