一、什么是观察者模式?

观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

二、类图及代码类

观察者模式Observer_System

观察者模式所涉及的角色:

1、抽象主题(Subject)角色:抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。
  2、具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。
  3、抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。
  4、具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。

       代码类:

抽象主题角色类 
public abstract class Subject {
/**
* 用来保存注册的观察者对象
*/
private List<Observer> list = new ArrayList<Observer>();
/**
* 注册观察者对象
* @param observer 观察者对象
*/
public void attach(Observer observer){

list.add(observer);
System.out.println("Attached an observer");
}
/**
* 删除观察者对象
* @param observer 观察者对象
*/
public void detach(Observer observer){

list.remove(observer);
}
/**
* 通知所有注册的观察者对象
*/
public void nodifyObservers(String newState){

for(Observer observer : list){
observer.update(newState);
}
}
}

  具体主题角色类

public class ConcreteSubject extends Subject{

private String state;

public String getState() {
return state;
}


public void change(String newState){
state = newState;
System.out.println("主题状态为:" + state);
//状态发生改变,通知各个观察者
this.nodifyObservers(state);
}
}

  抽象观察者角色类


public interface Observer {
/**
* 更新接口
* @param state 更新的状态
*/
public void update(String state);
}

  具体观察者角色类
public class ConcreteObserver implements Observer {
//观察者的状态
private String observerState;

@Override
public void update(String state) {
/**
* 更新观察者的状态,使其与目标的状态保持一致
*/
observerState = state;
System.out.println("状态为:"+observerState);
}


}


 
  客户端类
public class Client {
    public static void main(String[] args) {
        //创建主题对象
        ConcreteSubject subject = new ConcreteSubject();
        //创建观察者对象
        Observer observer = new ConcreteObserver();
        //将观察者对象登记到主题对象上
        subject.attach(observer);
        //改变主题对象的状态
        subject.change("new state");
    }
}

运行结果:

 Attached an observer

主题的状态为:new  state

观察者状态为:new state 

三、观察者模式的优点:

 
1、 Subject和Observer之间是松偶合的,分别可以各自独立改变。 
2、 Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。 
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。


四、观察者模式的应用场景: 
1、 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。 
2、 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。