观察者模式
是行为模式之一,作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象的状态。observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。
属于类和类之间的关系,不涉及到继承,观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知你。其实,简单来讲就一句话:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系。先来看看关系图:
我解释下这些类的作用:MySubject类就是我们的主对象,Observer1和Observer2是依赖于MySubject的对象,当MySubject变化时,Observer1和Observer2必然变化。AbstractSubject类中定义着需要监控的对象列表,可以对其进行修改:增加或删除被监控对象,且当MySubject变化时,负责通知在列表内存在的对象。
**********************************************************************************************************
角色: Subject 被观察者,当需要被观察者状态发生变化时候,需要通知队列中所有观察者对象,Subject 需要维持(添加,删除,通知)一个观察者对象的队列列表
ConcreteSubject 被观察者对象的具体实现,包含一些基本属性状态和其他操作
Observer 观察者 接口或者抽象类,当Subject被观察者状态发生改变时候,Observer对象通过一个 callback回调函数得到通知 ConcreteObserver:观察者具体实现,得到通知后将完成一些具体业务逻辑处理。;
实例一:自己事先观察者和被观察者的代码
*********************************************************************** //观察者接口 public interface Observer { public void update(); } *********************************************************************** //观察者1 public class Observer1 implements Observer{ @Override public void update() { System.out.println("observer1 has received!"); } } *********************************************************************** //观察者2 public class Observer2 implements Observer { @Override public void update() { System.out.println("observer2 has received!"); } } *********************************************************************** //定义了需要被监控的列表 public interface Subject { /*增加观察者*/ public void add(Observer observer); /*删除观察者*/ public void del(Observer observer); /*通知所有的观察者*/ public void notifyObservers(); /*自身的操作*/ public void operation(); } *********************************************************************** // public class AbstractSubject implements Subject { @Override public void operation() { } private Vector<Observer> vector = new Vector<Observer>(); @Override public void add(Observer observer) { vector.add(observer); } @Override public void del(Observer observer) { vector.remove(observer); } @Override public void notifyObservers() { Enumeration<Observer> enumo = vector.elements(); while(enumo.hasMoreElements()){ enumo.nextElement().update(); } } } *********************************************************************** public class MySubject extends AbstractSubject { @Override public void operation() { System.out.println("update self!"); notifyObservers(); } } *********************************************************************** //测试 public class MainClass { public static void main(String[] args) { Subject sub = new MySubject(); sub.add(new Observer1()); sub.add(new Observer2()); sub.operation(); } } ************************************************** 测试结果: update self! observer1 has received! observer2 has received!
********************************************
实例二:通过继承java自带的observerable和实现Observer接口调用
/** * 被观察对象 */ public class Person extends Observable { private String name; private int age; private String sex; public Person() { } public Person(String name, int age, String sex) { this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public void setName(String name) { //当被观察者发送变化时候,唤醒观察者调用回调函数更新 this.setChanged(); this.notifyObservers(); this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.setChanged(); this.notifyObservers(); this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.setChanged(); this.notifyObservers(); this.sex = sex; } } /** * 观察者 */ public class MyObserver implements Observer { @Override public void update(Observable o, Object arg) { System.out.println("观察者对象:对象发送改变!"); } }测试
/** * 观察者模式Observer */ public class MainClass { public static void main(String[] args) { Person p = new Person(); //注册观察者 p.addObserver(new MyObserver()); int i = p.countObservers(); System.out.println(i+"个观察者"); p.setAge(18); p.setName("蒸桑拿"); p.setSex("man"); System.out.println("---------------------"); Person person = new Person(); person.addObserver(new MyObserver()); person.setSex("男"); person.setName("lisi"); person.setAge(33); } } 测试结果 1个观察者 观察者对象:对象发送改变! 观察者对象:对象发送改变! 观察者对象:对象发送改变! --------------------- 观察者对象:对象发送改变! 观察者对象:对象发送改变! 观察者对象:对象发送改变!
************************************
实例三:
public class Article { private String articleTitle; private String articleContext; public String getArticleTitle() { return articleTitle; } public void setArticleTitle(String articleTitle) { this.articleTitle = articleTitle; } public String getArticleContext() { return articleContext; } public void setArticleContext(String articleContext) { this.articleContext = articleContext; } @Override public String toString() { return "Article{" + "articleTitle='" + articleTitle + '\'' + ", articleContext='" + articleContext + '\'' + '}'; } } /** *被观察者 */ public class BlogUser extends Observable { public void publishBlog(String articleTitle,String articleContext) { Article article = new Article(); article.setArticleTitle(articleTitle); article.setArticleContext(articleContext); System.out.println("博客发表新文章了,文章标题:"+articleTitle+",文章内容"+articleContext); this.setChanged(); //可以传递参数给观察者 this.notifyObservers(article); } } /** * 观察者 */ public class MyObserver implements Observer { @Override public void update(Observable o, Object arg) { //这个observer参数是具体的被观察者,arg是被观察者传递过来的参数,是个Object类型 System.out.println(o); System.out.println(arg); System.out.println("博主发表新文章了,快去看吧!"); } } /** * 发布订阅观察者和被观察者 */ public class MainClass { public static void main(String[] args) { BlogUser blogUser = new BlogUser(); blogUser.addObserver(new MyObserver()); blogUser.publishBlog("java虚拟机","内容是java虚拟机,从认识到精通"); } } 测试结果: 博客发表新文章了,文章标题:java虚拟机,文章内容内容是java虚拟机,从认识到精通 com.atguigu.observer.observerDemo2.BlogUser@135fbaa4 Article{articleTitle='java虚拟机', articleContext='内容是java虚拟机,从认识到精通'} 博主发表新文章了,快去看吧!