java设计模式-观察者模式
?
在观察者模式中我们必须定义一个所有“观察者”都必须实现的接口,这样被观察者向观察者发送消息的时候就可以使用统一的方式,这也符合面相对象原则中的面向接口编程:?
?1
//所有观察者都必须实现?
?2
public?interface?IBoy?
?3
{?
?4
//向男孩们显示小雪位置情况,也就是向观察者发送消息,观察者还可以对此做出反馈?
?5
void?Show(string?address);?}?
?6
?7
using?System;?
?8
//男孩A,一个观察者?
?9
public?class?BoyA?:?IBoy?
10
{?
11
public?void?Show(string?address)?
12
{?
13
//假设经过处理后为韩文的地址?
14
Console.WriteLine("A:"+address);?
15
}?
16
}?
17
using?System;?
18
//男孩B,又一个观察者?
19
public?class?BoyB?:?IBoy?
20
{?
21
public?void?Show(string?address)?
22
{?
23
//假设经过处理后为英语的地址?
24
Console.WriteLine("B:"+address);?
25
}?
26
}?
下面看看小雪的实现,也就是被观察者,主要看看那个订阅的电话列表和怎样将消息通知给观察者.
?1
using?System;??2
using?System.Collections.Generic;??3
public?class?GPRSMobile??4
{??5
//保存一个观察者列表??6
private?List<IBoy>?boys?=?null;??7
private?string?address?=?"";??8
public?GPRSMobile()??9
{?10
boys?=?new?List<IBoy>();?11
}?12
//添加观察者?13
public?void?AddBoy(IBoy?b)?14
{?15
boys.Add(b);?16
}?17
public?void?RemoveBoy(IBoy?b)?18
{?19
boys.Remove(b);?20
}?21
//通知?22
private?void?Notify(string?address)?23
{?24
for?(int?i?=?0;?i?<?boys.Count;?i++)?25
{?26
boys[i].Show(address);?27
}?28
}?29
//位置发生变化?30
public?void?OnAddressChanaged(string?newAddress)?31
{?32
//假设这里的地址是中文形式的?33
Notify(newAddress);?34
}?35
}?看到上面的代码例子,我们可以给观察者模式的实现总结出这样几条规律:第一,被观察者必须保存着一个观察者列表。第二,所有的观察者必须实现一个统一的接口。?
??? 那观察者模式到底有哪些好处呢?在上面的例子中我们可以看到被观察者仅仅依赖于一个实现了观察者接口的列表,我们可以随时的向这个列表添加观察者,而被观察者无须关注观察者是如何实现的。当我们向观察者族中添加一个新的观察者,被观察者无须作任何改变,新的类型只要实现了观察者接口即可。?
在上面的描述中我们仿佛看到了面向接口编程无穷的力量,面向接口编程使实现依赖于接口,也就是实现依赖于抽象。这样在被依赖对象发生改变的时候,只要接口没有发生变化时,依赖对象无须作任何变动。?
?? 在现实中存在着很多观察者模式的实例。比如在这个全民炒股的时代,每个持有股票的人总是不断的关注着自己所买的股票的走势,有人天天呆在交易大厅里看着屏幕上股票价格的走势,有人在工作时间盯着电脑里股票软件,为此很多公司采取各种各样的政策来制止这种行为,这样不仅影响正常的上班,且股票交易大厅常常人满为患。如果有这样一个服务,只要你订阅一个短信,这个服务就会在你所关注的股票价格发生变动的时候短信通知你,这样你就可以按照正常的顺序来做你的工作。