目录
一、观察者模式的应用场景
观察者模式应用在当一个对象改变的时候,会引起其他多个对象的改变;相当于消息发布者与消息监听者的一对多的依赖关系,观察者模式通过消息发布者抽象类与消息监听者抽象类的交互,实现松耦合,消息的监听者的数目可以动态变化,对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。
二、定义
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
三、UML图
四、实现方式
抽象主题:
/**
* 抽象主题
*/
public abstract class Subject {
private List<Observer> observers=new ArrayList<Observer>();
//增加观察者
public void attach(Observer observer){
observers.add(observer);
}
//删除观察者
public void detach(Observer observer){
observers.remove(observer);
}
//通知
public void notice(){
for(Observer ob:observers){
ob.update();
}
}
}
具体主题:
/**
* 具体主题
*/
public class ConcreteSubject extends Subject {
private String subjectState;
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String subjectState) {
this.subjectState = subjectState;
}
}
抽象观察者:
/**
* 抽象观察者
*/
public abstract class Observer {
public abstract void update();
}
具体观察者:
/**
* 具体观察者
*/
public class ConcreteObserver extends Observer {
private static Logger logger = LoggerFactory.getLogger(ConcreteObserver.class);
private String observerState;
private String name;
@Autowired
private ConcreteSubject subject;
public ConcreteObserver(ConcreteSubject subject,String name){
this.subject=subject;
this.name=name;
}
@Override
public void update(){
observerState=subject.getSubjectState();
logger.info("通知:{},拼购顾客*{}*请【确认签收】并【给出评价】",observerState,name);
}
}
客户端:
public class MinJson {
public static void main(String[] args) throws IOException {
try{
try{
ConcreteSubject cs=new ConcreteSubject();
cs.setSubjectState("快递到了");
cs.attach(new ConcreteObserver(cs,"张三"));
cs.attach(new ConcreteObserver(cs,"李四"));
cs.attach(new ConcreteObserver(cs,"王五"));
cs.notice();
}catch(Exception e){
}
}catch(Exception e){
}
}
}
实验结果:
通知:快递到了,拼购顾客*张三*请【确认签收】并【给出评价】
通知:快递到了,拼购顾客*李四*请【确认签收】并【给出评价】
通知:快递到了,拼购顾客*王五*请【确认签收】并【给出评价】
五、观察者模式的优缺点
优点:观察者模式实现主题的通知更新批量的观察者动作,只需要主题抽象类与观察者抽象类的交互,而无需关心具体的观察者与具体的主题的实现,实现主题与观察者的松耦合。
缺点:观察者模式实现一对多的通知更新,那么在有多对多的情况下,可能有主题的动作不同,不同类型主题适应的观察者类型不同。这样会用好多套观察者模式,开发量大,这时候可以考虑用事件委托实现。