设计模式随笔-发大米喽 (转)

吕震宇

每年到这个时候,工会都要给每位教工发大米、油什么的。正好我家的米快吃完了,所以这两天就盼着发大米,可是等了好多天也没见什么动静,扳着手指头数数离年根还有多半个月呢,看我心急的。不过,盼大米的老师恐怕不只是我一个,都等着工会有什么动静就去领大米呢。

其实,这里面还有很多东西可以拿来说说呢。教工等着发大米是一个典型的观察者模式,当工会大米来了,教工就会做出响应。不过这观察也有两种说头:一种是拉(Pull)模式,要求教工时不时到工会绕一圈,看看大米来了没有,恐怕没有人认为这是一种好办法。当然,还有另外一种模式,就是推(Push)模式,大米到了工会,工会会给每家每户把大米送过去。第二种方法好不好呢?好~~~~~呀!呵呵,谁说好了,谁说好我让谁到工会上班去。

其实,我们还有一种方法,就是大米到了工会后,工会不把大米给每人送去,而是给每人发个轻量级的"消息",教工得到消息后,再把大米"拉"回各家。这要求每位教工有一个工会的引用,在得到消息后到指定的地点领取大米。这样工会不用给每家教工送大米,而教工也不用每天到工会门口巴望着等大米了。

如果用代码来描述的化,就是这样一个观察者模式:

 

using System;
using System.Collections;

public class Teacher
{
  
private string name = "";
  
private GongHui g;

  
public Teacher(string name, GongHui g)
  
{
    
this.name = name;
    
this.g = g;
  }


  
public void RiceArrived()
  
{
    Console.WriteLine(
"{0}收到领大米的消息。", name);
    g.GetRice();
  }

}


public class Subject
{
  
protected ArrayList teachers = new ArrayList();

  
protected void Notify()
  
{
    
foreach(Teacher t in teachers)
      t.RiceArrived();
  }


  
public void Subscribe(Teacher s)
  
{ teachers.Add(s); }
}


public class GongHui : Subject
{
  
private int RiceLeft = 0;

  
public void RiceArrived(int n)
  
{
    
this.RiceLeft = n;
    Notify();
  }


  
public void GetRice()
  
{
    
if(RiceLeft > 0)
      Console.WriteLine(
"还剩 {0} 袋大米"--RiceLeft); 
    
else
      Console.WriteLine(
"抱歉,大米发完了,等下一拨吧。");
  }

}


public class Client
{
  
public static void Main( string[] args )
  
{
    GongHui g 
= new GongHui();

    g.Subscribe(
new Teacher("张三",g));
    g.Subscribe(
new Teacher("李四",g));
    g.Subscribe(
new Teacher("王五",g));

    g.RiceArrived(
2);
  }

}

有关观察者模式的更多信息,请参考《设计模式(19)-Observer Pattern》。

posted @ 2007-10-11 13:22  智慧园区-老朱  阅读(208)  评论(0编辑  收藏  举报