java观察者

本文介绍了一种常用的设计模式——观察者模式,详细解释了其核心概念及组成部分,并通过实例演示了如何实现一对多的关系,使得当主题发生变化时,所有观察者能够自动更新。

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

观察者模式,一对多的关系,也存在一对一的关系,多个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("我是班主任,现在上自习你们看自己的");
	}
}


结果:
自己运行一次吧!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值