关闭

观察者模式

49人阅读 评论(0) 收藏 举报
<span style="font-size:14px;">假设,我们现在有一个Person类,该类有以下方法

class Person{
   public void run() {
    System.out.println("run!!");   
  }
   public void eat() {
      System.out.println("eat!!");   
    }
}</span>

现在这个类想要被别人监听,那么,我们就需要提供一个接口(也就是监听器),暴露我们的方法;

于是这个接口就是下面这个样子:

<span style="font-size:14px;">interface PersonListener{
	public void dorun();
	public void doeat();
}</span>

在该接口中,我们暴露了Person类的2个方法,当外部实现监听器的时候,就可以在相对应的监听方法下,写自己的方法。


但是,这么做,我们无法在被监听对象的某个方法被触发的时候,调用监听器的方法,因为该监听器根本就没有监听Person对象。

那么如何做?

我们需要将事件源封装到事件对象中,

<span style="font-size:14px;">class Even{
	private Person person;
	public Even() {
		super();
	}

	public Even(Person person) {
		super();
		this.person = person;
	}
	public Person getPerson() {
		return person;
	}

	public void setPerson(Person person) {
		this.person = person;
	}
}</span>

接着将事件对象变为接口中方法的一个参数。

于是,接口就被改造为:

<pre name="code" class="java"><span style="font-size:14px;">interface PersonListener{
	public void dorun(Even even);
	public void doeat(Even even);
} </span>


接下来,为了能够在Person类中调用监听对象中的方法。我们需要在被监听对象中维护一个监听器对象;

<span style="font-size:14px;">class Person{
	private PersonListener listener;
	public void registerListener(PersonListener listener){
		this.listener = listener;
	}
	public void run(){	 
		System.out.println("runn!!");
	}
	public void eat(){	 
		System.out.println("eat!!");
	}
}</span>

好,现在,在被监听器对象中维护了一个监听器对象。那么我们接下去要做的,就是在被监听对象中调用监听器相应的方法。

<span style="font-size:14px;">class Person{
	private PersonListener listener;
	public void registerListener(PersonListener listener){
		this.listener = listener;
	}
	public void run(){
		<strong><span style="color:#FF0000;">if(listener!=null){
			Even even = new Even(this);
			this.listener.dorun(even);
		}</span>  </strong><span style="color:#3333FF;"><strong>//注意这2段红色字体的代码; 当该对象没有注册监听器的时候(也就是没有调用registerListener方法),调用的是对象本身自己的方法,如果注册了监听,
那么listener 对象将不为空, 也就是说,将调用监听器的方法和对象本身的方法,这样该对象就被监听了</strong>
</span>
     System.out.println("runn!!");
	}
	public void eat(){
		<strong><span style="color:#FF0000;">if(listener!=null){
			Even e = new Even(this);
			this.listener.doeat(e);
		}</span></strong>
		System.out.println("eat!!");
	}
}</span>

这样就是一整个的观察者模式;下面给出完整的全部代码:

<span style="font-size:14px;">//事件源
class Person{
	private PersonListener listener;
	public void registerListener(PersonListener listener){
		this.listener = listener;
	}
	public void run(){
		if(listener!=null){
			Even even = new Even(this);
			this.listener.dorun(even);
		}
		System.out.println("runn!!");
	}
	public void eat(){
		if(listener!=null){
			Even e = new Even(this);
			this.listener.doeat(e);
		}
		System.out.println("eat!!");
	}
}
//事件监听器
interface PersonListener{
	public void dorun(Even even);
	public void doeat(Even even);
}
//事件对象(封装事件源)
class Even{
	private Person person;
	public Even() {
		super();
	}

	public Even(Person person) {
		super();
		this.person = person;
	}

	public Person getPerson() {
		return person;
	}

	public void setPerson(Person person) {
		this.person = person;
	}
}</span>

下面给出测试类:

<span style="font-size:14px;">public class Demo {
	public static void main(String[] args) {
		Person p = new Person();
		p.registerListener(new MyListener1());
		p.eat();
		p.run();
	}
}
class MyListener1 implements PersonListener{

	public void doeat(Even even) {
		System.out.println(even.getPerson()+"吃吃吃!!");
	}

	public void dorun(Even even) {
		System.out.println(even.getPerson()+"跑跑跑!!");
		
	}	
}</span>




0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1961次
    • 积分:136
    • 等级:
    • 排名:千里之外
    • 原创:12篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条