设计模式系列漫谈之一 - 观察者模式
此文为转载,地址: http://yuyijq.cnblogs.com/
故事
小雪是一个非常漂亮的女孩,漂亮的女孩总是有很多的追求者,而且追求者的队伍在不断的变动,随时有人进入这个队伍,也有人退出。男孩们追求女孩时总是表现出120%的关心,当小雪私自游玩时总是不断收到追求者询问小雪位置变动的消息,小雪也不胜其烦,但小雪是如此的一个善良的女孩,她总是打断自己正常的生活回复男孩们的消息。而男孩们由于要不断的关心小雪的位置变化也弄的精疲力竭,而且还影响正常的工作。
小雪和男孩们的烦恼:
男孩们必须不断的询问小雪的位置变化,从而打断正常的工作小雪也要不断的接受男孩们的询问,有的时候小雪的位置并没有发生变化,还是要不断的回复男孩们的询问。如果给各个男孩们回复问题的方式都不尽相同,小雪还要知道不同的回复方式。
我们给小雪和男孩们提出了解决方案:
建议小雪购买一款带有GPRS功能的手机,该手机保存着所有追求者的电话号码,当该手机检测到小雪的位置发生变化时, 就会向所有追求者通知所在位置。这样一来,男孩们和小雪都各自都可以按照自己正常的生活习惯,只有小雪所在位置发生变化时候才会进行通信。
观察者模式(Observer)的解决方案
观察者模式的思想:观察者模式定义了被观察者与观察者对象之间一对多关系,当被观察者对象的状态发生改变时,多个观察者对象就会接受到通知。
观察者接口如下:
namespace XiaoXue
{
public interface IObserver
{
void ShowAddress(string address);
}
}
{
public interface IObserver
{
void ShowAddress(string address);
}
}
观察者类如下:
namespace XiaoXue
{
public class BoyA : IObserver
{
public void ShowAddress(string address)
{
Console.WriteLine("小雪所在位置:" + address);
}
}
public class BoyB : IObserver
{
public void ShowAddress(string address)
{
Console.WriteLine("小雪所在位置:" + address);
}
}
}
{
public class BoyA : IObserver
{
public void ShowAddress(string address)
{
Console.WriteLine("小雪所在位置:" + address);
}
}
public class BoyB : IObserver
{
public void ShowAddress(string address)
{
Console.WriteLine("小雪所在位置:" + address);
}
}
}
被观察者类如下:
namespace XiaoXue
{
public class GPRSMobile
{
private ArrayList boys = new ArrayList(); //观察者列表
public GPRSMobile()
{
}
public void AddBoy(IObserver b)
{
boys.Add(b);
}
//通知所有观察者
private void Notify(string address)
{
for (int i = 0; i < boys.Count; i++)
{
IObserver boy=(IObserver)boys[i];
boy.ShowAddress(address);
}
}
//当位置发生变化时执行
public void OnAddressChanaged(string newAddress)
{
Notify(newAddress);
}
}
}
{
public class GPRSMobile
{
private ArrayList boys = new ArrayList(); //观察者列表
public GPRSMobile()
{
}
public void AddBoy(IObserver b)
{
boys.Add(b);
}
//通知所有观察者
private void Notify(string address)
{
for (int i = 0; i < boys.Count; i++)
{
IObserver boy=(IObserver)boys[i];
boy.ShowAddress(address);
}
}
//当位置发生变化时执行
public void OnAddressChanaged(string newAddress)
{
Notify(newAddress);
}
}
}
客户端调用如下:
BoyA boya=new BoyA();
BoyB boyb=new BoyB();
GPRSMobile mobile=new GRPSMobile()
mobile.AddBoy(boya);
mobile.AddBoy(boyb);
BoyB boyb=new BoyB();
GPRSMobile mobile=new GRPSMobile()
mobile.AddBoy(boya);
mobile.AddBoy(boyb);
GPRS手机一旦监测所在位置发生变化,立即调用OnAddressChanaged方法发送信息
mobile.OnAddressChanaged("小雪在纽约向你问好!");