举个例子:
出版社订阅报纸就是观察者模式;
1, 出版者一旦有新的报纸,就必须发送给订阅了报纸的对象;
2, 已订阅的人可以取消订阅报纸,同时不会再接收到报纸;
3, 任何人可以申请订阅报纸,申请后就会收到报纸;
观察者模式:定义了对象之间的一(出版社)对多(订报者)依赖,这样依赖,当一个对象(出版社来报纸了)改变状态时,它的所有的依赖者都会收到通知并自动更新;
设计原则:
1. 找出程序中会变化的方面,然后将其和固定不变的方面分离开;
2. 针对接口编程,不针对实现编程;
3. 多用组合,少用继承;
针对以上问题,有如下设计图:
实现如下所示:
主题(出版社的基类):
interface Subject{
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
出版社类如下:
public class publishingHouse implements Subject{
private ArrayList<Observer> observers;
private String newPaper;//新报纸的名字
@Override
public void registerObserver(Observer o) {
// TODO Auto-generated method stub
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
// TODO Auto-generated method stub
int i = observers.indexOf(o);
if(i>=0){
observers.remove(i);
}
}
@Override
public void notifyObservers() {
// TODO Auto-generated method stub
for(Observer o:observers){
o.update(newPaper);
}
}
public void hasReceiveNew(String newPaper){
this.newPaper = newPaper;
notifyObservers();
}
}
观察者接口:
interface Observer{
public void update(String newPaper);
}
不同的观察者:
class xiaoming implements Observer{
private String newPaper;
private Subject pHouse;
public xiaoming(Subject pHouse){
this.pHouse = pHouse;
pHouse.registerObserver(this);
}
@Override
public void update(String newPaper) {
// TODO Auto-generated method stub
this.newPaper = newPaper;
}
}
Java内置了观察者模式,提供了Observable类(主题基类),和Observer接口;
上面的设计如果采用java内置的接口和类,它的设计应该如下所示:
该类Observable的比较重要的部分的伪代码如下;
setChanged(){
changed = true;
}
//arg代表的数据对象,可以就newPaper作为参数传入,但是我没//有这么做
notifyObservers(Object arg){
if(changed){
for everyobserver on the list{
call update(this,arg)
}
}
clearChanged();
}
notifyObservers(){
notifyObservers(null);
}
实现代码如下:
class publishHouse extends Observable{
private int newPaper;
public void hasReceiveNew(int newPaper){
this.newPaper = newPaper;
setChanged();
notifyObservers();
}
public int getNewPaper(){
return newPaper;
}
}
class xiaoming1 implements Observer{
Observable observable;
private int newPaper;
public xiaoming1(Observable observable){
this.observable = observable;
observable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
if(o instanceof publishHouse){
newPaper = ((publishHouse)o).getNewPaper();
display();
}
}
public void display(){
System.out.println("小明新的报纸:"+newPaper);
}
}
class xiaohong1 implements Observer{
Observable observable;
private int newPaper;
public xiaohong1(Observable observable){
this.observable = observable;
observable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
if(o instanceof publishHouse){
newPaper = ((publishHouse)o).getNewPaper();
display();
}
}
public void display(){
System.out.println("小红新的报纸:"+newPaper);
}
}
测试如下:
public class test {
public static void main(String arg[]){
publishHouse subject = new publishHouse();
xiaoming1 a = new xiaoming1(subject);
xiaohong1 b = new xiaohong1(subject);
subject.hasReceiveNew(1);
subject.hasReceiveNew(2);
}
}
在JDK中,Swing事件处理采用了观察者模式,下列大致了解下;
Jbutton继承(不是直接继承哈)于主题基类JComponent(事件的触发源);ActionListener相当于观察者接口;
(主题类JComponent定义了EventListenerLIstlistenerList 容器 来存储触发的事件,类似于ArrayList<Observer>obsservers;)
以此有如下可实现的代码:
public class testSwing {
JFrame frame;
public static void main(String[] args){
testSwing tests = new testSwing();
tests.start();
}
public void start(){
frame = new JFrame();
JButton button = new JButton("test");
button.addActionListener(new doit());
button.addActionListener(new notdoit());
frame.getContentPane().add(BorderLayout.CENTER,button);
frame.setVisible(true);
frame.setSize(200,200);
}
class doit implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.out.println("doit");
}
}
class notdoit implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.out.println("notdoit");
}
}
}