Observer
The different objects got some dependency with each others. when the state of one of them is changed. all other dependent object will be notified and updated by some predefined rules.It is like the Publish-Subscribe mode, when the publisher is changed, all the subsciber will be changed automatically even the publisher don't know how many subscciber it has.
When we use this pattern
As talked above.if you have below situation. you are recommended to use the observer pattern:
- the objects got some dependency BUT the individual object can be reused and run independently
- when a object is changed, you got to notify the another
- you got to notify the another. BUT the publisher even doesn't know how many objects(Subscriber) there is
Roles in this pattern
- Subject: where you can define the interfaces used for attaching or deattaching the observer.
- Observer:Define a update interface for the concreteObservers that is gonna be updated and notified when the subject is changed.
- ConcreteSubject:Store the concrete observers and send the msm to the Concrete observers and notify them
- ConcreteObserver:Get a reference of the ConcreteObserver and Update the own state and keep its state when it is notified.
- Client
It is gorgeous because the Subject even doesnot know how many observers it has, acutually there is no need to know.The Subject is just responsible for the "Notify". the rest will be done by the observers themself by their own ways.
The observers don't know each other. they don't affect each other too anyway.They just do their own work after being notified, just update themself.
For short: the subject is dedicated to NOTIFY. the observers are dedicated to observe(==to listen) and then do what they should do.
one more thing:there is gonna be as many concrete subject as you want. and as many concrete observer as you want. most importantly the very concrete observer can freely choose the very concrete subject as it wants.
Actually the Subject and Observer described in the roles are two interfaces. so application are decoupled with the benefit of the interface.
A small demo to demonstrate this pattern:
namespace Observer
{
public interface Subject
{
void Attach(Observer observer);
void Detach(Observer observer);
void Notify();
string SubjectState
{
get;
set;
}
}
public abstract class Observer
{
protected string observerName;
protected Subject subject;
public Observer(string observerName, Subject subject)
{
this.observerName = observerName;
this.subject = subject;
}
public abstract void Update();
}
public class ConcreteSubject : Subject
{
private List<Observer> observers = new List<Observer>();
private string action;
public void Attach(Observer observer)
{
observers.Add(observer);
}
public void Detach(Observer observer)
{
if (observers.Count > 0)
{
observers.Remove(observer);
}
}
public void Notify()
{
foreach (Observer observer in observers)
{
observer.Update();
}
}
public string SubjectState
{
get
{
return action;
}
set
{
this.action = value;
}
}
}
public class ConcreteObserver : Observer
{
public ConcreteObserver(string observerName, Subject subject)
: base(observerName, subject)
{
}
public override void Update()
{
//here do what you wanna do
}
}
class Client
{
static void Main(string[] args)
{
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver observer = new ConcreteObserver("testName", subject);
subject.Attach(observer);
subject.SubjectState = "My state is changed";
subject.Notify();
}
}
}
Real examples:
there are lots of examples in ASP.NET: like delegate, event. they are all substitutes for the observer pattern(actually they ARE observer patterns).
the above demo can be smoothly implemented by the delegate or event.(one got a event, the others who listen to the event will run automatically).