观察者(Observer)模式浅析

观察者模式又称为发布订阅模式,是对象的行为模式。观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监视着被观察者的状态,当被观察者的状态发生变化时,会通知所有的观察者,并让其自动更新自己。
那这里我用一个老师和课代表的例子来客观的表示观察者模式。
例如:老师有很多的作业,他会分别告诉各科的课代表,每当有新作业时,就会把这个作业告诉对应的课代表,于是就有了这样的伪代码:

if(老师有新作业了){
	告诉语文课代表语文作业;
	告诉数学课代表数学作业;
}

如果作业很多的情况的话,那就需要改变这段伪代码:

if(老师有新作业了){
	告诉语文课代表语文作业;
	告诉数学课代表数学作业;
	告诉英语课代表英语作业;
	告诉物理课代表物理作业;
	告诉化学课代表化学作业;
}

按照这样的方法,如果还有其他科目的作业,那么还要继续在if里面添加逻辑。首先,如果多达十几门学科,那么id语句的逻辑就会异常复杂了。这样代码耦合就会增加很多,其次,这样会在if语句里堆积太多的代码,不利于维护,同时造成扩展困难。
而观察者模式更易于扩展,责任也更加清晰。首先,把每一个课代表看成一个观察者,每个观察者都能观察到作业列表(被监听对象)。当老师发布了新作业时,就会发送到这个作业列表上,于是作业列表(被监听对象)发生了变化,这时就可以出发各个课代表接口(观察者)发送新作业到对应的课代表那里。观察者模式示例如下图所示:
在这里插入图片描述
类似于这样,一个对象(课代表接口)会去监听另外一个对象(作业列表),当被监听对象(作业列表)发生变化时,对象(课代表接口)就会触发一定的行为,以适合变化的逻辑模式,我们称之为逻辑模式,课代表接口被称为观察者或者监听者,作业列表被称为被观察者或者被监听者。

下面我用一个代码实例来展示观察者模式。
观察者模式要同时存在观察者和被观察者双方,观察者可以是多个。在Java中,需要去继承java.util.Observable类,先看被观察者——一个作业列表,代码如下所示:
ZuoyeList.java

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;


public class ZuoyeList extends Observable{
	private List<String> ZuoyeList=null;    //作业列表
	private static ZuoyeList instance;     //类唯一实例
	//构建方法私有化
	private ZuoyeList() {
		
	}
	
	/**
	 * 取得唯一实例
	 * @return 作业列表唯一实例
	 */
	public static ZuoyeList getInstance() {
		if(instance==null) {
			instance=new ZuoyeList();
			instance.ZuoyeList=new ArrayList<String>();
		}
		return instance;
	}
	
	/**
	 * 增加观察者(课代表接口)
	 * @param observer 观察者
	 */
	public void addZuoyeListObserver(Observer observer) {
		this.addObserver(observer);
	}
	
	/**
	 * 新增产品
	 * @param newZuoye 新作业
	 */
	public void addZuoye(String newZuoye) {
		ZuoyeList.add(newZuoye);
		System.out.println("作业列表新增加了作业:"+newZuoye);
		this.setChanged();					//设置被观察者对象发生了变化
		this.notifyObservers(newZuoye);		//通知观察者,并传递新作业
	}
}

这个类的一些基本内容和主要方法如下:

  • 构造方法私有化,避免通过new的方式去创建对象,而是通过getInstance方法获得作业列表单例。
  • addZuoyeListObserver方法可以增加一个作业接口(观察者)。
  • 核心逻辑在addZuoye方法上。在作业列表上增加一个新作业,然后调用setChanged方法。这个setChanged方法用于告知观察者当前被观察者发生了变化,如果没有,则无法触发其行为。最后通过notifyObservers告知观察者,让它们发生相应的动作,并将新作业作为参数传递给观察者。

这时已经有了被观察对象,还要去编写观察者。仍以语文课代表和数学课代表为例,去实现它们的作业接口。作为观察者需要实现java.util.Observer接口的update方法,代码如下:
YuwenObserver.java

	import java.util.Observable;
	import java.util.Observer;
	
	public class YuwenObserver implements Observer{
	
		@Override
		public void update(Observable o, Object zuoye) {
			// TODO Auto-generated method stub
			String newZuoye=(String) zuoye;
			System.out.println("发送新作业【"+newZuoye+"】同步到语文课代表");
		}
	}

ShuxueObserver.java

import java.util.Observable;
import java.util.Observer;

public class ShuxueObserver implements Observer{

	@Override
	public void update(Observable o, Object zuoye) {
		// TODO Auto-generated method stub
		String newZuoye=(String) zuoye;
		System.out.println("发送新作业【"+newZuoye+"】同步到数学课代表");
	}
	
}

测试代码:
test.java


public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ZuoyeList observable=ZuoyeList.getInstance();
		YuwenObserver yuwwenObserver=new YuwenObserver();
		ShuxueObserver shuxueObserver=new ShuxueObserver();
		observable.addObserver(yuwwenObserver);
		observable.addObserver(shuxueObserver);
		observable.addZuoye("新作业123");
	}

}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值