观察者模式学习

1.观察者模式又称为订阅者模式

1)观察者模式中有如下几个角色:

抽象观察者        Observer

具体观察者        ObserverA,ObServerB

抽象主题            Subject

具体主题            SubjectA

2)观察者模式又分为推方式和拉方式:

推方式:主题对象推送主题的详细信息,不管观察者是否需要。

拉方式:主题对象在通知观察者的时候,只传递少量信息,如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当于观察者到主题对象中拉数据。一般这种模型中,会将主题对象自身通过update()方法传递给观察者,这样在观察者需要获取数据的时候,就可以通过这个引用方式获取了。

说明:推方式,推送的主题的详细信息,拉方式,推送的是具体主题对象。

   

3)Java标准支持的观察者模式

在Java中,提供了一个Obseverable类以及一个Observer接口,构成了Java语言对观察者模式的支持。

Observer接口只定义了一个update()方法,当被观察者对象的状态发生改变时,被观察者对象的notiryObservers()方法就会调用这个方法。

Observer类是被观察者的基类。

2.示例演示

1)推方式示例代码

interface Observer{            //抽象观察者
	public void update(String  state);
}
//具体观察者A
class ObserverA implements Observer{
	private String myState;
	
	public void update(String state){
		myState = state;
	}
	
	public String getState(){
		return myState;
	}
}
//具体观察者B
class ObserverB implements Observer{
	private String myState;
	public void update(String state){
		myState = state;
	}
	
	public String getState(){
		return myState;
	}
}

abstract class Subject{
	List<Observer> list = new ArrayList<>();
	public void register(Observer observer){		//观察者注册
		list.add(observer);
	}
	
	public void remove(Observer observer){			//观察者删除
		list.remove(observer);
	}
	
	public void notifyAllObserver(String state){	//更新所有观察者的状态
		for(Observer observer:list){
			observer.update(state);
		}
	}
}

class SubjectA extends Subject{
	private String changeState;
	
	
	public void setMessage(String changeMessage){
		this.changeState = changeMessage;
		this.notifyAllObserver(changeMessage);
	}

	
	public String getState(){
		return changeState;
	}
}



class Test{
	public static void main(String[] args) {
		ObserverA obvA = new ObserverA();	//创建观察者A
		ObserverB obvB = new ObserverB();	//创建观察者B
		
		SubjectA sub = new SubjectA();
		sub.register(obvA);
		sub.register(obvB);
		sub.setMessage("状态一");
		System.out.println(obvA.getState());;
		System.out.println(obvB.getState());;
		
		System.out.println("---------------");
		sub.setMessage("改变状态");
		System.out.println(sub.getState());
		System.out.println(obvA.getState());;
		System.out.println(obvB.getState());;
	}
}
2)拉方式示例代码
//抽象观察者
interface Observer{
	public void update(Subject sub);
}

//具体观察者
class ObserverA implements Observer{
	String state;
	public void update(Subject sub){		//相比与推方式,这里参数是具体主题,观察者可以根据需要获取需要信息
		this.state = ((SubjectA)sub).myState;
	}
	
	public String getState(){
		return state;
	}
}

class ObserverB implements Observer{
	String state;
	public void update(Subject sub){
		this.state = ((SubjectA)sub).myState;
	}
	
	public String getState(){
		return state;
	}
}

//抽象主题
abstract class Subject{
	List<Observer> list = new ArrayList<>();
	public void register(Observer observer){	//注册观察者
		list.add(observer);
	}
	
	public void remove(Observer observer){		//删除观察者
		list.remove(observer);	
	}
	
	public void notifyAllObserver(){
		for(Observer observer:list){
			observer.update(this);				//更新观察者
		}
	}
}

//具体主题
class SubjectA extends Subject{
	String myState;
	public void setState(String myState){
		this.myState = myState;
		this.notifyAllObserver();
	}
	
	public String getState(){
		return myState;
	}
}

class Test{
	public static void main(String[] args) {
		ObserverA observerA = new ObserverA();
		ObserverB observerB = new ObserverB();
		SubjectA sub = new SubjectA();
		sub.register(observerA);		//注册
		sub.register(observerB);		//注册
		sub.setState("状态一");
		System.out.println(observerA.getState());
		System.out.println(observerB.getState());
		
		System.out.println("---------推送-----------");
		sub.setState("改变状态一");
		System.out.println(observerA.getState());
		System.out.println(observerB.getState());
		
	}
}

说明:notifyAllObserver()函数在推方式中是只能放在具体主题中,而在拉方式中方抽象主题中和具体主题中都是可以的

3)使用观察者库

库中已经有了抽象观察者接口Oberver和抽象主题类Observable,我们直接使用就行了。

class ObserverA implements Observer{
	String state;
	@Override
	public void update(Observable o, Object arg) {
		this.state = ((SubjectA)o).getState();        //显然库中也是使用的拉方式
	}
	
	public String getState(){
		return state;
	}
}

class ObserverB implements Observer{
	String state;
	@Override
	public void update(Observable o, Object arg) {
		this.state = ((SubjectA)o).getState();
	}
	
	public String getState(){
		return state;
	}
}

class SubjectA extends Observable{	//这里的Observer相当于上面写的类Subject
	private String myState;
	public void setState(String state){
		this.myState = state;
		this.setChanged();
		this.notifyObservers();   //相当于上面写的notiyfyAllObserver();
	}
	public String getState(){
		return myState;
	}
}

class Test{
	public static void main(String[] args) {
		ObserverA obA = new ObserverA();
		ObserverB obB = new ObserverB();
		SubjectA sub = new SubjectA();
		sub.addObserver(obA);
		sub.addObserver(obB);
		sub.setState("状态一");
		System.out.println(obA.getState());
		System.out.println(obB.getState());
		
		System.out.println("-------改变状态-------");
		sub.setState("改变状态一");
		System.out.println(obA.getState());
		System.out.println(obB.getState());
	}
}

参考:

https://blog.youkuaiyun.com/itachi85/article/details/50773358
https://blog.youkuaiyun.com/yanbober/article/details/45484749

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值