传说,好莱坞有一条规则:别来找我,我会去找你。
观察者模式,有两种角色:观察者,以及通知者(或者叫目标对象)。
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
单谈概念总是很虚,让我们来看一个实例:
假设我们有一个商城,有这么样一个需求,当商城上架新的商品时,要将产品推送到各个合作商家,伪代码如下:
if(上架新商品){
推送商品到天猫。
推送商品到京东。
...
}
那么,这样就会有一个问题,当每增加一个合作商家,就有修改这段代码,这肯定会后期的维护带来一些问题。
这时候,观察者模式就派上用场了。
这里,商城就是我们的通知者,而各个合作商家就是观察者。
让我们一步步把这段代码使用观察者模式重构。
1. 首先定义一个接口,名叫Observer,拥有一个update方法:
public interface Observer {
void update(Product product);
}
这个接口是对各个商家的抽象,我们不关心具体你是哪个商家,只需知道你是一个observer即可。
2. 接下来定义我们的商城,它应该拥有一个成员变量,来存储合作商家。这里,Shop需要对外暴露一个接口,这个接口可以让外部注册观察者。在本个案例当中,就是合作商家通过这个接口像商城注册。
public class Shop {
private List<Observer> observerList=new ArrayList<>();
public void addObserver(Observer observer){
observerList.add(observer);
}
3.最后,我们需要一个Product类,没有具体实现,用来传递商品信息。
好,现在让我们来编写上架商品通知合作商家的代码:
private Thread thread=new Thread(()->{
while(true){
for(Observer observer:observerList){
observer.update(new Product());
}
}
});
{
thread.start();
}
我们通过一个线程来模拟这个商城每隔1秒上架一个新商品,并推送给合作商家。
接下来,来编写两个合作商家具体实现类:
Tmall和Jd:
public class Tmall implements Observer {
@Override
public void update(Product product) {
System.err.println("天猫收到了商品推送:"+product);
}
}
public class Jd implements Observer {
@Override
public void update(Product product) {
System.err.println("京东收到了消息推送:"+product);
}
}
最后,让我们来运行下这个商城,并把京东和天猫注册到商城的观察者列表里:
public static void main(String[] args) {
Shop shop=new Shop();
shop.addObserver(new Jd());
shop.addObserver(new Tmall());
}
运行结果:
京东收到了消息推送:wang.ismy.observer.Product@1306033d
天猫收到了商品推送:wang.ismy.observer.Product@3797d4bd
京东收到了消息推送:wang.ismy.observer.Product@77bdc880
天猫收到了商品推送:wang.ismy.observer.Product@a5d83c1
京东收到了消息推送:wang.ismy.observer.Product@2961765c
天猫收到了商品推送:wang.ismy.observer.Product@20da7df1
京东收到了消息推送:wang.ismy.observer.Product@39ba58a2
天猫收到了商品推送:wang.ismy.observer.Product@5f1f97df
…