Observer模式

in 未分类

GOF设计模式其中之一,observer也称观察者模式。
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
UML图:

Subject,所有被观察者的基类,该类可定义为抽象的,或干脆提升为interface。
Attach方法是附加一个观察者,Detach方法是移除一个观察者
Notify方法将自动通告所有观察者,在上图中就是
foreach o in observers
  o.Update()

Observer,所有观察者的基类,该类可定义为抽象,或定义为interface。

ConcreteSubject 具体的被观察者
ConcreteObserver 具体的观察者

比如现实中的例子:
拍卖演示了这种模式。每个投标人都有一个标有数字的牌子用于出价。拍卖师开始拍卖时,他观察是否有牌子举起出价。
每次接受一个新的出价都改变了拍卖的当前价格,并且广播给所有的投标人进行新的出价。

基本的Observer模式

 

using System;
using System.Collections;


namespace DoFactory.GangOfFour.Observer.Structural
{

  // MainApp test application  

  class MainApp
  {
    static void Main()
    {
      // 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  
      s.SubjectState = "ABC";
      s.Notify();

      // Wait for user  
      Console.Read();
    }

  }


  // "Subject"  

  abstract class Subject
  {
    private ArrayList observers = new ArrayList();

    public void Attach(Observer observer)
    {
      observers.Add(observer);
    }


    public void Detach(Observer observer)
    {
      observers.Remove(observer);
    }


    public void Notify()
    {
      foreach (Observer o in observers)
      {
        o.Update();
      }

    }

  }


  // "ConcreteSubject"  

  class ConcreteSubject : Subject
  {
    private string subjectState;

    // Property  
    public string SubjectState
    {
      get{ return subjectState; }
      set{ subjectState = value; }
    }

  }


  // "Observer"  

  abstract class Observer
  {
    public abstract void Update();
  }


  // "ConcreteObserver"  

  class ConcreteObserver : Observer
  {
    private string name;
    private string observerState;
    private ConcreteSubject subject;

    // Constructor  
    public ConcreteObserver(
      ConcreteSubject subject, string name)
    {
      this.subject = subject;
      this.name = name;
    }


    public override void Update()
    {
      observerState = subject.SubjectState;
      Console.WriteLine("Observer {0}’s new state is {1}",
        name, observerState);
    }


    // Property  
    public ConcreteSubject Subject
    {
      get { return subject; }
      set { subject = value; }
    }

  }

}

 

输出结果:

Observer X’s new state is ABC
Observer Y’s new state is ABC
Observer Z’s new state is ABC

 

3 Comments

3 Comments

  1. 搜索引擎对老幻的blog比较亲赖

  2. 的确
    我也发现了这一点

  3. 这二天头疼得利害~~~

Leave a Reply

Using Gravatars in the comments - get your own and be recognized!

XHTML: These are some of the tags you can use: <a href=""> <b> <blockquote> <code> <em> <i> <strike> <strong>