当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。好比,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。ide
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,全部依赖于它的对象都获得通知并被自动更新。code
主要解决:一个对象状态改变给其余对象通知的问题,并且要考虑到易用和低耦合,保证高度的协做。server
什么时候使用:一个对象(目标对象)的状态发生改变,全部的依赖对象(观察者对象)都将获得通知,进行广播通知。对象
如何解决:使用面向对象技术,能够将这种依赖关系弱化。接口
应用实例:1.拍卖的时候,拍卖师观察最高标价,而后通知给其余竞价者竞价。
2.打团时每一个职业作不一样的事情。class
优势: 一、观察者和被观察者是抽象耦合的。 二、创建一套触发机制。List
缺点: 一、若是一个被观察者对象有不少的直接和间接的观察者的话,将全部的观察者都通知到会花费不少时间。 二、若是在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能致使系统崩溃。 三、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。循环
简单的说就是:多个对象去观察一个对象是否发出号令(消息),而后作出相应响应动做
以DNF打团为例子:
当团长发出攻坚开始的消息时全部的队友开始输出。程序
建立一个职业的抽象类(观察者接口):Hero
技术
public abstract class Hero { /** * 打团 * @param msg */ public abstract void datuan(String msg); }
分别建立三个职业(观察者)
建立一个红眼:Hongyan
public class Hongyan extends Hero { private static final String ROLE = "帝血弑天"; @Override public void datuan(String msg) { System.out.println(msg+ ROLE +":血魔:弑天! "); } }
建立一个奶爸:Naiba
public class Naiba extends Hero { private static final String ROLE = "神思者"; @Override public void datuan(String msg) { System.out.println(msg + ROLE + ": 阿波克列!"); } }
建立一个篮拳:Lanquan
public class Lanquan extends Hero { private static final String ROLE = "正义仲裁者"; @Override public void datuan(String msg) { System.out.println(msg+ ROLE + ":粉碎吧!"); } }
建立一个团长(被观察者):Captain
public class Captain { private List<Hero> heroes = new ArrayList<>(); public void setMsg(String msg) { notifyAll(msg); } //订阅 public void addTeam(Hero hero) { heroes.add(hero); } //通知全部订阅的观察者 private void notifyAll(String msg) { for (Hero observer : heroes) { observer.datuan(msg); } } }
主程序:Main
public class Main { public static void main(String[] args) { Lanquan lanquan = new Lanquan(); Hongyan hongyan = new Hongyan(); Naiba naiba = new Naiba(); Captain captain = new Captain(); captain.addTeam(lanquan); captain.addTeam(hongyan); captain.addTeam(naiba); captain.setMsg("超时空攻坚战开始-"); } }
执行结果:
超时空攻坚战开始-正义仲裁者:粉碎吧! 超时空攻坚战开始-帝血弑天:血魔:弑天! 超时空攻坚战开始-神思者: 阿波克列!