java观察者模式学习总结



观察者模式在Java语言中的地位极其重要,JDK也提供了对观察者模式的内置支持,实现思路是:Observable类用于创建主题类,当这种子类的对象发生变化时,观测类被通知,观测类必须实现定义了update()方法的Observer接口。 当一个观测程序被通知到一个被观测对象的改变时,update()方法被调用。

下面学习到自己搭建观察者模式的步骤:

1、创建两个接口,一个是抽象的主题角色(被观察的对象),一个是抽象的观察者角色。

package observer;

/*
 * 抽象的主题角色
 */
public interface Watched
{
	//这里Watcher是一个接口
	public void addWathcer(Watcher watcher);
	
	public void removeWatcher(Watcher watcher);
	
	public void notifyWatchers(String str);

}


package observer;

/*
 * 抽象的观察者角色
 */
public interface Watcher
{
	public void update(String str);	
}


2、创建两个角色的实现类

package observer;

import java.util.ArrayList;
import java.util.List;

public class ConcreteWatched implements Watched
{
	//创建一个集合,用来承载观察自己的观察者们
	private List<Watcher> list = new ArrayList<Watcher>();
	
	@Override
	public void addWathcer(Watcher watcher)
	{
		list.add(watcher);
	}

	@Override
	public void removeWatcher(Watcher watcher)
	{
		list.remove(watcher);
	}

	//主题对象在此处调用观察者对象,在AWT中是在内部实现,外部看不到,会误以为是自动调用,其实是由主题调用
	@Override
	public void notifyWatchers(String str)
	{
		for(Watcher watcher : list)
		{
			watcher.update(str);
		}
	}
}

package observer;

public class ConcreteWatcher implements Watcher
{
	@Override
	public void update(String str)
	{
		System.out.println(str);
	}
}


3、创建测试类,实现观察者模式

package observer;

public class test
{
	public static void main(String[] args)
	{
		/*
		 * 对应到AWT模型中,观察者模式就容易理解了
		 */
		//相当于按钮
		Watched origin = new ConcreteWatched();
		
		Watcher watcher1 = new ConcreteWatcher();
		Watcher watcher2 = new ConcreteWatcher();
		Watcher watcher3 = new ConcreteWatcher();
		
		//相当于添加监听器
		origin.addWathcer(watcher1);
		origin.addWathcer(watcher2);
		origin.addWathcer(watcher3);
		
		//相当于点击按钮
		origin.notifyWatchers("First notity");
		
		origin.removeWatcher(watcher3);
		
		origin.notifyWatchers("Second notify");			
	}
}


在学习过程中,对观察者模式的理解,最重要的在于第2步中主题对象调用观察者对象,通过遍历所有观察者,实现观察者中的方法。其次还有主题中使用集合建立与观察者之间的关联。

由于观察者模式在AWT,swing中使用很广泛,学习观察者模式有助于swing中按钮添加监听事件的原理,并不是自动实现方法调用,而是作为主题的按钮实现了对事件的调用。

通过练习观察者模式,进一步体会到了接口的作用(因为单纯的看这个例子不禁会想到-为什么明明可以用类直接实现的,还要多设计两个接口,接口(抽象主题、观察者角色)在这里的作用是什么?):

原由:在创建主题类和观察者类时,完全可以不使用接口,如下:

		ConcreteWatched origin = new ConcreteWatched();
		
		ConcreteWatcher watcher1 = new ConcreteWatcher();
		ConcreteWatcher watcher2 = new ConcreteWatcher();
		ConcreteWatcher watcher3 = new ConcreteWatcher();

解释:  
  此处也是多态的使用,在这个例子中只对Watched和Watcher接口实现了一种类,没有体现出使用接口的优势
  如果有多个方法相同的类而不使用接口,创建不同主题角色,就要改变一次其参数类型,看上去很混乱
  如: ConcreteWatched1:public void addWathcer(ConcreteWatcher1 watcher){}
     ConcreteWatched2:public void addWathcer(ConcreteWatcher2 watcher){}
  而利用接口抽象出来后,主题角色的参数类型用接口表示就无需改变其参数类型,只需实现本身的功能就可以
     ConcreteWatched1:public void addWathcer(Watcher watcher){}
     ConcreteWatched2:public void addWathcer(Watcher watcher){}
  说到底,就是接口在java中的作用:
  达到统一访问,就是在创建对象的时候用接口创建,
  【接口名】【对象名】 = new 【实现接口的类】,
  这样用哪个类的对象就可以new哪个对象了,不需要改原来的代码。
  主要体现在多个类实现同一个接口时,统一访问的优势才会发挥出来
  而且,在使用时,多态的使用使代码更整齐易懂


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值