观察者模式

介绍

使用频率非常高的一个设计模式,最常用的地方,是发布系统的订阅功能。这个模式的一个重要的作用是解耦,将观察者跟被观察者的依赖性降到最小,甚至毫无依赖。

使用场景

消息订阅等

简单实现

程序员订阅开发者网站,当网站有内容更新的时候,会通知所有订阅了的开发者。

程序员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Coder implements Observer {

public String name;

public Coder(String name){
this.name=name;
}

@Override
public void update(Observable observable, Object o) {
System.out.println("Hi,"+name+",DevWebSite 更新了,内容:"+o);
}

@Override
public String toString(){
return "码农:"+name;
}

}

Coder代表程序员,实现了Observer接口,是具体的观察者,而Observer是抽象的观察者。Observer是JDK的内置类型。

网站

1
2
3
4
5
6
7
8
9
public class DevWebSite extends Observable {

public void postNewPublication(String content){
//表示内容或者状态发生改变
setChanged();
//通知所有的观察者
notifyObservers(content);
}
}

DevWebSite是具体的主题角色,Observable是抽象的主体角色。Observable是JDK的内置的类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Test {

public static void main(String[] args){

DevWebSite devWebSite = new DevWebSite();

Coder codeA = new Coder("A");
Coder codeB = new Coder("B");
Coder codeC = new Coder("C");
Coder codeD = new Coder("D");

devWebSite.addObserver(codeA);
devWebSite.addObserver(codeB);
devWebSite.addObserver(codeC);
devWebSite.addObserver(codeD);

devWebSite.postNewPublication("你拿到offer了.");

}
}

打印内容:
Hi,D,DevWebSite 更新了,内容:你拿到offer了.
Hi,C,DevWebSite 更新了,内容:你拿到offer了.
Hi,B,DevWebSite 更新了,内容:你拿到offer了.
Hi,A,DevWebSite 更新了,内容:你拿到offer了.

Coder是具体的观察者,他订阅了DevWebSite这个具体的可观察的对象,当内容有更新的时候,会遍历所有的观察者,然后给这些观察者发布一个更新的消息,即调用Coder的update方法,这样就达到了一对多的通知的功能。在这个过程中,通知系统都是依赖于Observer和Observable这些抽象类,因此对于Coder跟DevWebSite完全没有耦合,保证了订阅系统的灵活性跟可靠性。

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器