//主题,抽象通知者,一般由一个抽象类或者接口 abstract class Subject { private IList<Observer> observers = new List<Observer>(); //增加观察者 public void Attach(Observer obs) { observers.Add(obs); } //移除观察者 public void Detach(Observer obs) { observers.Remove(obs); } //通知 public void Notify() { foreach (Observer item in observers) { item.Update(); } } }
//具体通知者 class ConcreteSubject : Subject { private string subjectState; //具体被观察者状态 public string SubjectState { get { return subjectState; } set { subjectState = value; } } }
//抽象观察者,为所有的具体观察者定义一个接口,用于更新自己 abstract class Observer { public abstract void Update(); }
//具体观察者 class ConcreteObserver : Observer { private string name; private string observerState; private ConcreteSubject subject;//观察的对象 public ConcreteSubject Subject { get { return subject; } set { subject = value; } } public ConcreteObserver(ConcreteSubject subject, string name) { this.subject = subject; this.name = name; } //观察者做出回应 public override void Update() { observerState = subject.SubjectState; Console.WriteLine("观察者 {0} 的新状态是 {1}", name, observerState); } }
顾名思义,当一个对象的改变需要同时改变其他对象的时候,而且不知道具体有多少对象有待改变时,应该考虑使用观察者模式。观察者模式所做的工作其实就是在接触耦合,让耦合的双方都依赖于抽象,而不是依赖于具体。//主程序代码
public class MainProgram { public void Main() { ConcreteSubject s = new ConcreteSubject(); //首先创建主题对象 s.Attach(new ConcreteObserver(s, "1")); //添加观察者 s.Attach(new ConcreteObserver(s, "2")); s.Attach(new ConcreteObserver(s, "3")); s.SubjectState = "逃跑"; s.Notify(); //通知 Console.ReadKey(); } }
//具体观察者 class ConcreteObserver { private string name; private string observerState; private ConcreteSubject subject; public ConcreteSubject Subject { get { return subject; } set { subject = value; } } public ConcreteObserver(ConcreteSubject subject, string name) { this.subject = subject; this.name = name; } public void Update() { observerState = subject.SubjectState; Console.WriteLine("观察者 {0} 的新状态是 {1}", name, observerState); } }
//通知者接口 interface class Subject { //通知 void Notify(); }
//具体通知者 class ConcreteSubject : Subject {
public delegate void EventHandler(); //声明委托,无参数和返回值
public event EventHandler Update; //创建一个委托事件变量
private string subjectState; //具体被观察者状态 public string SubjectState { get { return subjectState; } set { subjectState = value; } }
public void Notify(){
Update(); //直接调用委托变量
}
}
委托对象所搭载的所有方法必须具有相同的原形和形式,也就是拥有相同的参数列表和返回值类型。//客户端代码
public class MainProgram
{
public void Main()
{
ConcreteSubject s = new ConcreteSubject(); //首先创建主题对象
ConcreteObserver obs1 = new ConcreteObserver("1"); //添加观察者s.Update += new ConcreteSubject.EventHandler(obs1.Update); //添加通知事件
ConcreteObserver obs2 = new ConcreteObserver("2");
s.Update += new ConcreteSubject.EventHandler(obs2.Update);
ConcreteObserver obs3 = new ConcreteObserver("3");s.Update += new ConcreteSubject.EventHandler(obs3.Update);
s.Notify(); //通知
Console.ReadKey();
}
}