java观察者模式

本文介绍了Java观察者模式的概念和应用,通过出版社与订阅者的例子阐述了一对多的依赖关系。设计原则强调了变化隔离、接口编程和组合使用。文章还展示了如何实现观察者模式,并提及Java内置的Observable类和Observer接口。此外,文章讨论了Swing事件处理如何利用观察者模式,以JButton和ActionListener为例进行说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

举个例子:

出版社订阅报纸就是观察者模式;

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");
		}
	}
}



















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值