◎筱米加步枪◎.Blog

Happy coding

观察者模式

筱米加步枪 posted @ 2010年3月08日 01:22 in [ 设计模式 ] with tags 设计模式 观察者模式 , 2577 阅读

今天,在公司看了一整天的设计模式之--观察者模式,查了许多相关资料,先总结下:

首先确定观察者模式的角色,实际上观察者模式中设计的角色是2中:观察者和被观察者(目标)

但从设计模式上去分:又分成四种,目的是有利于扩展和增加代码的弹性。

1.目标接口

2.具体目标

3.观察者接口

4.具体观察者

观察者模式通俗点讲,其实就是反应现实当中一对多的关系,这个“一”就是目标,“多”就是观察者。

当目标有新的信息或者信息发生改变,要通知在该目标所管的范围内的所有观察者。

比如:

1.老师和学生 ,老师通知一个事情的时候,所有在这个班级的同学都要接收到通知。老师就是目标,学生就是观察者

2.一个商品和关注该商品的客户,当这个商品的价格发生变化的时候,要通知所有关注该商品的客户。商品就是目标,客户商就是观察者

3.孩子和父母的关系,当孩子在学校发生的事情要告诉父母,孩子就是目标,父母就是观察者。

 

以老师和学生的关系为例,写了如下代码:

1.目标接口:

**
 * 被观察者接口(主题对象)
 * 
 * @author ChenST
 *
 * @create 2010-3-8
 */
public interface Subject {
	
	/**
	 * 添加一个观察者
	 * @param observer 观察者
	 */
	public void addObserver(Observer observer);
	
	/**
	 * 删除一个观察者
	 * @param observer 观察者
	 */
	public void deleteObserver(Observer observer);
	
	/**
	 * 通知所有的观察者消息
	 */
	public void notifyObservers();
	
}

2.目标接口的实现:

/**
 * 
 * 老师类-->一个被观察者(通知者)
 * 
 * @author ChenST
 *
 * @create 2010-3-8
 */
public class Teacher implements Subject {
	/**
	 * 要通知的消息
	 */
	private String message;
	
	/**
	 * 所有的观察者集合(所有的学生)
	 */
	private List<Observer> students;
	
	public Teacher(){
		message="";
		students=new ArrayList<Observer>();
	}
	
	/*
	 * 当本班级有新同学加入时,新同学也能够收到老师的通知
	 * (non-Javadoc)
	 * @see com.shine.model.subject.Subject#addObserver(com.shine.model.observer.Observer)
	 */
	public void addObserver(Observer observer) {
		this.students.add(observer);
	}

	/*
	 * 当本班级有同学有退学的时候,这位同学以后就不能收到老师的通知了
	 * (non-Javadoc)
	 * @see com.shine.model.subject.Subject#deleteObserver(com.shine.model.observer.Observer)
	 */
	public void deleteObserver(Observer observer) {
		int index=students.indexOf(observer);
		if(index>=0){
			students.remove(observer);
		}
	}

	/*
	 * 所有人都能够收到老师的通知
	 * (non-Javadoc)
	 * @see com.shine.model.subject.Subject#notifyObservers()
	 */
	public void notifyObservers() {
		for(Observer observer:this.students){
			observer.update(this);
		}
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}
}

3.观察者接口:

/**
 * 
 * 观察者接口--抽象出来,代表观察者
 * 
 * @author ChenST
 *
 * @create 2010-3-8
 */
public interface Observer {
	
	/**
	 * 观察者实时更新自己所得到的消息
	 * @param 被观察者对象,可获取被观察者里面的信息
	 */
	public void update(Subject subject);
	
}

4.观察者接口的实现:

/**
 * 学生类,观察者,当老师有事情要宣布时,学生能够收到信息
 * 
 * @author ChenST
 *
 * @create 2010-3-8
 */
public class Student implements Observer{
	
	/**
	 * 学生姓名
	 */
	private String name;

	public Student(String name){
		this.name=name;
	}
	
	/*
	 * 更新自己的通知<-->有新通知到来
	 * (non-Javadoc)
	 * @see com.shine.model.observer.Observer#update()
	 */
	public void update(Subject subject) {
		if(subject instanceof Teacher){
			Teacher teacher=(Teacher)subject;
			System.out.println(this.name+"同学接到老师的通知:"+teacher.getMessage());
		}
	}
}

5.测试类:模拟场景。

/**
 * 测试类:模拟老师通知学生的场景
 * 
 * @author ChenST
 *
 * @create 2010-3-8
 */
public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//一个老师
		Teacher teacher=new Teacher();
		//两个学生,并加入这个班级
		Observer student1=new Student("张三");
		teacher.addObserver(student1);
		Observer student2=new Student("李四");
		teacher.addObserver(student2);
		
		//通知消息
		teacher.setMessage("明天不上课");
		teacher.notifyObservers();
		
		//王五同学加入本班级
		Observer student3=new Student("王五");
		teacher.addObserver(student3);
		//通知消息
		teacher.setMessage("后天期末考");
		teacher.notifyObservers();
		//张三同学退学了,并通知大家
		teacher.deleteObserver(student1);
		teacher.setMessage("张三同学退学了");
		teacher.notifyObservers();
	}
}

运行结果:

张三同学接到老师的通知:明天不上课
李四同学接到老师的通知:明天不上课
张三同学接到老师的通知:后天期末考
李四同学接到老师的通知:后天期末考
王五同学接到老师的通知:后天期末考
李四同学接到老师的通知:张三同学退学了
王五同学接到老师的通知:张三同学退学了

实现完毕~~看来一些材料,说Java内置的观察者模式也可实现相同功能~~日后学习之~~


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter