观察者模式Java版 http://blog.csdn.net/nyzhl/archive/2007/12/09/1926130.aspx
在Java中实现观察者模式,需要在被观察者中持有所有观察者的引用,这样观察者和被观察对象之间存在一定的耦合,只有实现观察者接口的类的对象才可以注册到被观察者中,不够灵活。
也许是我在吹毛求疵,因为Java已经做的很好了,但是在C#中,有更好的解决方法-Deleget & Event 。
被观察对象不再需要持有观察者的引用,只需要定义一个事件,而委托 事件是与类型无关的,它可以指向任意类的某个函数(当然要符合委托的返回值,参数声明),非常灵活,消除了观察者和被观察对象的耦合。
还是昨天的例子:闹钟(被观察对象)响(发送消息),人(观察者)被惊醒(做出响应)。
using
System;
// 委托声明
public delegate void AlarmHandler();
public class AlarmClock ... {
//事件声明
private event AlarmHandler AlarmEvent;
public void Alarm() ...{
//事件触发
if(AlarmEvent!=null) ...{
AlarmEvent();
}
}
//观察者注册
public void Registry(Person p) ...{
//事件队列的注册
this.AlarmEvent += new AlarmHandler(p.Wake);
}
}
public class Person ... {
private string _name;
public Person(string name) ...{
this._name = name;
}
public void Wake() ...{
Console.WriteLine(this._name + " is awake");
}
}
public class Test ... {
public static void Main() ...{
AlarmClock clock = new AlarmClock();
Person nyzhl = new Person("Zhao Hongliang");
Person Bob = new Person("Bob");
Person Jenny = new Person("Jenny");
clock.Registry(nyzhl);
clock.Registry(Bob);
clock.Registry(Jenny);
clock.Alarm();
}
}
// 委托声明
public delegate void AlarmHandler();
public class AlarmClock ... {
//事件声明
private event AlarmHandler AlarmEvent;
public void Alarm() ...{
//事件触发
if(AlarmEvent!=null) ...{
AlarmEvent();
}
}
//观察者注册
public void Registry(Person p) ...{
//事件队列的注册
this.AlarmEvent += new AlarmHandler(p.Wake);
}
}
public class Person ... {
private string _name;
public Person(string name) ...{
this._name = name;
}
public void Wake() ...{
Console.WriteLine(this._name + " is awake");
}
}
public class Test ... {
public static void Main() ...{
AlarmClock clock = new AlarmClock();
Person nyzhl = new Person("Zhao Hongliang");
Person Bob = new Person("Bob");
Person Jenny = new Person("Jenny");
clock.Registry(nyzhl);
clock.Registry(Bob);
clock.Registry(Jenny);
clock.Alarm();
}
}
Bob is awake
Jenny is awake