观察者模式,一对多的关系,也存在一对一的关系,多个observer以及一个subject,当subject发生改变时,各observer收到通知,并做出相应的反应。
观察者模式,就是观察对象做出反应,那么观察者做出相应的反应,各自执行自己相应的方法。
一般来说 观察者模式有四个的对象
一:抽象主题角色:把所有对观察者对象保存在一个Arraylist集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。
具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。
现在我就一代码的形式来说下什么是观察者模式的简单通用代码
抽象主题角色
package com.whoami; import java.util.ArrayList; import java.util.List; /** * * @author ZhangYong *观察者接口,知道观察他的观察者,能够添加观察者和删除观察者 */ public class Subject { private List<Observer> observers = new ArrayList<Observer>(); public void add(Observer observer){ observers.add(observer); } public void remove(Observer observer){ observers.remove(observer); } protected void notifyObservers(){ for(Observer observer:observers){ observer.update(this); } } }
抽象观察者角色
package com.whoami; /** * 观察者接口。 * @author ZhangYong * */ public interface Observer { /** * 更新接口 * @param subject * subject传入目标对象,方便获取状态 */ public void update(Subject subject); }
具体主题角色
package com.whoami; /** * 具体的被观察的观察对象 * @author ZhangYong * */ public class SpecificSubject extends Subject { //目标对象状态 private String subjectState; public String getSubjectState() { return subjectState; } public void setSubjectState(String subjectState) { this.subjectState = subjectState; this.notifyObservers(); } }
具体观察者角色
package com.whoami; /** * 继承观察者接口。具体实现update的方法 * @author ZhangYong * */ public class SpecificObserver implements Observer { //观察者状态 private String observerState; public String getObserverState() { return observerState; } public void setObserverState(String observerState) { this.observerState = observerState; } public void update(Subject subject) { observerState = ((SpecificSubject)subject).getSubjectState(); System.out.println(); } }
现在我来说下如何使用上面的通用代码来改编为想要的观察者模式(多应用在线程中)。 来个简单的例子。不知道同学们是不是经常在乎班主任啊。那么现在班主任就是我们的观察者对象,同学就是观察者。
那么我们来实现以下:当班主任说现在开始上自习,那么同学就是在接受到班主任的通知后,A同学看数学,B同学看物理,C同学看英语等等。那怎么实现呢。
抽象主题角色
package com.whoami; import java.util.ArrayList; import java.util.List; /** * * @author ZhangYong *观察者接口,知道观察他的观察者,能够添加观察者和删除观察者 */ public class Subject { private List<Observer> observers = new ArrayList<Observer>(); public void add(Observer observer){ observers.add(observer); } public void remove(Observer observer){ observers.remove(observer); } protected void notifyObservers(){ for(Observer observer:observers){ observer.update(this); } } }
抽象观察者角色
package com.whoami; /** * 观察者接口。 * @author ZhangYong * */ public interface Observer { /** * 更新接口 * @param subject * subject传入目标对象,方便获取状态 */ public void update(Subject subject); } 具体主题角色 package com.whoami; /** * 具体的被观察的观察对象(班主任) * @author ZhangYong * */ public class SpecificSubject extends Subject { //目标对象状态 private String subjectState; public String getSubjectState() { return subjectState; } /** * * 班主任发布通知 * @param subjectState */ public void setSubjectState(String subjectState) { this.subjectState = subjectState; this.notifyObservers(); } }
具体观察者角色
package com.whoami; /** * 继承观察者接口。具体实现update的方法 * @author ZhangYong * */ public class SpecificObserver implements Observer { //观察对象通知 private String observerState; //观察者姓名,标记吧 private String observerName; //观察者将要做什么,也可以是个方法 private String observerThings; public String getObserverState() { return observerState; } public void setObserverState(String observerState) { this.observerState = observerState; } public String getObserverName() { return observerName; } public void setObserverName(String observerNae) { this.observerName = observerNae; } public String getObserverThings() { return observerThings; } public void setObserverThings(String observerThings) { this.observerThings = observerThings; } /** * 接收到通知,响应事件,现在先打印一句话 */ public void update(Subject subject) { observerState = ((SpecificSubject)subject).getSubjectState(); System.out.println(observerName+"得到观察对象的通知是:"+observerState+",即将做出:"+observerThings); } }
现在还差什么呢?当然是一个测试类啦,不然怎么知道成果怎么样啊。下面我们就创建一个测试类Main
package com.whoami; /** * @author ZhangYong *测试类 */ public class Main { public static void main(String[] args) { //创建观察者对象 SpecificObserver man1 = new SpecificObserver(); man1.setObserverName("同学A"); man1.setObserverThings("我想看数学"); SpecificObserver man2 = new SpecificObserver(); man2.setObserverName("同学B"); man2.setObserverThings("我想看物理"); SpecificObserver man3 = new SpecificObserver(); man3.setObserverName("同学C"); man3.setObserverThings("想看英语"); //添加对象到集合众 SpecificSubject sub = new SpecificSubject(); sub.add(man1); sub.add(man2); sub.add(man3); //观察对象发布通知,创建目标 sub.setSubjectState("我是班主任,现在上自习你们看自己的"); } }
结果:
自己运行一次吧!!!