观察者模式
2018-09-20 本文已影响0人
wxz1997
一、定义
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新,也叫做发布订阅模式
优点:观察者和和被观察者之间是抽象耦合,容易进行扩展。可以用来建立一套触发机制,形成触发链。
缺点:需要考虑效率问题,一个观察者卡壳,会影响整体效率。一般采取异步方式解决
二、实现
public class Client {
public static void main(String[] args) {
//创建一个被观察者
ConcreteSubject subject = new ConcreteSubject();
//定义一个观察者
Observer obs= new ConcreteObserver();
//观察者观察被观察者
subject.addObserver(obs);
//观察者开始活动了
subject.doSomething();
}
}
//被观察者
abstract class Subject {
//定义一个观察者数组
private List<Observer> list = new ArrayList<>();
//增加一个观察者
public void addObserver(Observer o){
this.list.add(o);
}
//删除一个观察者
public void delObserver(Observer o){
this.list.remove(o);
}
//通知所有观察者
public void notifyObservers(){
System.out.println("已发布消息");
for(Observer o:this.list){
o.update();
}
}
}
//具体被观察者
class ConcreteSubject extends Subject {
//具体的业务
public void doSomething() {
/*
* do something
*/
super.notifyObservers();
}
}
//抽象观察者
interface Observer {
//更新方法
void update();
}
//具体观察者
class ConcreteObserver implements Observer {
//实现更新方法
public void update() {
System.out.println("接收到信息,并进行处理!");
}
}
三、JDK自带的类
public class Client {
public static void main(String[] args) {
//创建一个被观察者
ConcreteSubject subject = new ConcreteSubject();
//定义一个观察者
Observer obs = new ConcreteObserver();
//观察者观察被观察者
subject.addObserver(obs);
//观察者开始活动了
subject.doSomething();
}
}
abstract class Subject{
}
//具体被观察者
class ConcreteSubject extends Observable {
//具体的业务
public void doSomething() {
/*
* do something
*/
setChanged();
super.notifyObservers("发布消息了");
}
}
//具体观察者
class ConcreteObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("开始接收");
System.out.println("接受到消息:" + arg.toString());
System.out.println("接收完毕");
}
}
四、注意
- 它和责任链模式的最大区别就是观察者广播链在传播的过程中消息是随时更改的,它是由相邻的两个节点协商的消息结构;而责任链模式在消息传递过程中基本上保持消息不可变,如果要改变,也只是在原有的消息上进行修正。建议在一个观察者模式中最多出现一个对象既是观察者也是被观察者,也就是说消息最多转发一次(传递两次)。
- 保证快速响应的方法有:一是采用多线程技术,也就是异步架构;二是缓存技术,也就是同步架构。
- 可以采用类似setChanged(),来决定是否通知观察者。