二、观察者模式(老师与学生的故事)
目录:
出处:http://blog.csdn.net/yungd112/article/details/43022839
提示:如果要转载,请标明出处!
1.描述
观察者模式(有时又被称为发布-订阅Subscribe>模式、模型-视图View>模式、源-收听者Listener>模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通 知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
观察者模式定义了对象之间的一对多的依赖,这样依赖,当一个对象改变状态是,它的所有依赖者都会收到通知并更新状态。比如(学生需要老师的知识)
2.设计原则
针对接口编程,而不是针对实现编程。要使对象之间松耦合
3.解决问题
例如(广播、报纸订阅、天气预报)这种的一对多依赖关系,但是不要思维定式,一对一的话如果也有一方数据更新需要通知另一方的话,也可以用观察者模式
4.角色
Subject 主题抽象对象
Teacher 继承Subject,并且实现,Teacher为主题实例
Observer 观察者抽象对象
Student 继承Observer,并且实现,Studednt为观察者实例
5.缺陷
6.UML图
7.代码
主题:Subject.java
/**
* @filename Subject.java
* @description 主题
* @author WuRenqing
* @create 2015年1月22日 下午4:18:32
* @copyright Copyright (c) 2014
*
*/
public abstract class Subject {
private Vector<Observer> observers;
public Subject(){
observers=new Vector<Observer>();
}
public Vector<Observer> getObservers() {
return observers;
}
public void setObservers(Vector<Observer> observers) {
this.observers = observers;
}
//添加观察者
public void addObserver(Observer observer){
if(observer!=null && !observers.contains(observer))
observers.addElement(observer);
}
//删除观察者
public void deleteObserver(Observer observer){
observers.removeElement(observer);
}
//通知观察者
public abstract void notifyObserver(Object arg);
//默认通知
public void defaultNotify(Object arg){
for(int index=0;index<observers.size();index++){
observers.get(index).update(this,arg);
}
}
}
主题对象(老师):Teacher.java
public class Teacher extends Subject {
@Override
public void notifyObserver(Object arg) {
Map<String, Object> map=(Map<String, Object>)arg;
if(map.get("normal")!=null){
System.out.println(map.get("normal"));
}
}
}
观察者:Observer.java
/**
* @filename Observer.java
* @description 观察者
* @author WuRenqing
* @create 2015年1月22日 下午4:15:11
* @copyright Copyright (c) 2014
*
*/
public abstract class Observer {
public abstract void update(Subject subject,Object arg);
}
观察者对象(学生):Student.java
public class Student extends Observer {
private String name;//学生姓名
private int num;//座号
@Override
public void update(Subject subject, Object arg) {
Map<String, Object> data=(Map<String, Object>)arg;
//当有学生加入的时候,学生的反应
if(data.get("addStudents")!=null){
System.out.println(this.name+":欢迎"+data.get("addStudents")+"跟我一起受折磨!");
}
//当知道有人离开了,学生的反应
if(data.get("delStudents")!=null){
System.out.println(this.name+":"+data.get("delStudents")+"真幸运,终于脱离苦海了!");
}
//当知道有学生被惩罚的时候,学生的反应
if(data.get("punishStudents")!=null){
if(!data.get("punishStudents").equals(this.name))
System.out.println(this.name+":嘿嘿,"+data.get("punishStudents")+"又受罚了,大快人心啊!");
else
System.out.println(this.name+":啊!我不活了,为什么受伤的总是我!");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
运行测试:Test.java
public class test {
public static void main(String[] args) throws ClassNotFoundException
{
Teacher t =new Teacher();
Student xiaohua=new Student();
//创建3个学生
xiaohua.setName("小花");
xiaohua.setNum(1);
Student xiaoming=new Student();
xiaoming.setName("小明");
xiaoming.setNum(2);
Student xiaohei=new Student();
xiaohei.setName("小黑");
xiaohei.setNum(3);
//先加入小花、小黑这两个学生
t.addObserver(xiaohua);
t.addObserver(xiaohei);
Map<String, Object> map=new HashMap<String, Object>();
//老师:告诉大家一下小明要加入我们班集体了
map.put("addStudents", "小明");
//老师:看看大家什么反应
t.defaultNotify(map);
//...小明加入了
t.addObserver(xiaoming);
//小花:这老师讲课太糟糕了,不堪入耳。得赶紧逃
t.deleteObserver(xiaohua);
map.clear();
//老师:告诉大家一个不幸的消息,小花走了,剩下你们两个男的搞基吧!
map.put("delStudents", "小花");
//老师:看看学生们什么反应
t.defaultNotify(map);
//...不幸的是,小黑的话被老师听到了
//老师:小黑,外面站去
map.clear();
map.put("punishStudents", "小黑");
t.defaultNotify(map);
}
}
8.运行结果