您的位置:首页 > 编程语言 > Java开发

Java设计模式之观察者模式

2016-09-27 15:38 295 查看
一、概念描述

观察者模式属于行为型模式,其意图是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

这一个模式的关键对象是目标(Subject)和观察者(Observer)。一个目标可以有任意数目的依赖它的观察者,一旦目标的状态发生改变,所有的观察者都得到通知,作为对这个通知的响应,每个观察者都将查询目标以使其状态与目标的状态同步。

二、适用场景

观察者模式,用于存在一对多依赖关系的对象间,当被依赖者变化时,通知依赖者全部进行更新。因此,被依赖者,应该有添加/删除依赖者的方法,且可以将添加的依赖者放到一个容器中;且有一个方法去通知依赖者进行更新。

三、观察者模式的结构



观察者模式所涉及的角色有:

抽象主题(Subject)角色:抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。

具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。

抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。

具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。

四、一个实例

老师有一个电话号码,学生需要知道老师的电话号码以便于在需要的时候拨打,当老师的电话号码发生改变时,学生得到通知,并更新相应的电话记录。在这样的组合中,老师就是一个被观察者(Subject),学生就是需要知道信息的观察者(Observer)。

源码:

抽象主题(Subject)角色:

package com.test.observer;

public interface Subject {

public void attach(Observer o);
public void detach(Observer o);

public void notice();

}


具体主题(ConcreteSubject)角色:

package com.test.observer;

import java.util.Vector;

public class Teacher implements Subject{

private String phone;
private Vector students;

public Teacher() {
phone = "";
students = new Vector();
}

@Override
public void attach(Observer o) {
students.add(o);

}

@Override
public void detach(Observer o) {
students.remove(o);

}

/**
* 当目标状态发生改变时,发布通知给观察者
*/
@Override
public void notice() {
for(int i=0;i<students.size();i++){
((Observer)students.get(i)).update();
}

}

public void setPhone(String phone) {
this.phone = phone;
notice();
}

public String getPhone() {
return phone;
}

}


抽象观察者(Observer)角色:

package com.test.observer;

public interface Observer {

public void update();
}


具体观察者(ConcreteObserver)角色:

package com.test.observer;

public class Student implements Observer{

private int student_id;
private String teacher_phone;

private Teacher teacher;

public Student(int student_id,String teacher_phone) {
// TODO Auto-generated constructor stub
this.student_id = student_id;
this.teacher_phone = teacher_phone;

}
public Student(int student_id,Teacher teacher) {
// TODO Auto-generated constructor stub
this.student_id = student_id;
this.teacher = teacher;
}

/**
* 当收到目标通知后更新
*/
@Override
public void update() {

teacher_phone = teacher.getPhone();

}

public void show(){
System.out.println("id:"+ student_id + "  teacher_phone:"+teacher_phone);
}

}


测试主类:

package com.test.observer;

import java.util.Vector;

public class Client {

public static void main(String[] args) {
// TODO Auto-generated method stub
Vector students = new Vector();

Teacher teacher = new Teacher();

for(int i=0;i<10;i++){
Student student = new Student(i,teacher);
students.add(student);
teacher.attach(student);
}

teacher.setPhone("10086-123");
for(int i=0;i<10;i++){
((Student)students.get(i)).show();
}

}

}


运行结果:

id:0  teacher_phone:10086-123
id:1  teacher_phone:10086-123
id:2  teacher_phone:10086-123
id:3  teacher_phone:10086-123
id:4  teacher_phone:10086-123
id:5  teacher_phone:10086-123
id:6  teacher_phone:10086-123
id:7  teacher_phone:10086-123
id:8  teacher_phone:10086-123
id:9  teacher_phone:10086-123


Observer模式的最知名的应用是在MVC结构,Observer模式可以很好的应用在文档和图表程序的制作中。

参考:

http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html

http://www.cnblogs.com/hnrainll/archive/2011/12/29/2305582.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息