【设计模式】观察者模式

说明:这是一种一对多的依赖关系,多个观察者同时监听某一个主题对象,当对象发生改变时,会通知所有的观察者对象(Observer),是他们能够及时更新自己,这个模式在生活中很常见,比如最简单的rss订阅,电子商务等都用到了这种模式。

这里特别值得一提的是在在jdk的工具(util)包中也有这种设计模式的具体实现类(java.util.Observer,java.util.Observerable)。其中Observer是观察者,Observerable是被观察的目标(subject)。只要分别继承和实现Observerable和Observer就可以实现该功能了。

 

下面我们看下具体的代码实现吧!

1.观察者(Observer接口),仅有一个抽象方法update,此方法接收两个参数,分别表示被观察的对象以及被观察的具体值(value),当被观察的目标值(value)改变后,便会把新的value传到这个方法里。当然这个接口必须由实现类实现它。

public interface Observer
{
	public void update(Observerable observersable,Object value);
}


2.被观察的目标(Observable),这个类有众多方法,其中的精髓就是ArrayList集合和notifyObservers方法,整个类都在维护这个集合,而notifyObservers这个方法也是通过遍历集合来通知所有的观察者对象。下面我们研究下这个类吧!

这个类有两个字段(成员变量):ArrayList型的observers和boolean型的hasChanged,其中ArrayList集合中存放的是许多Observer对象,我们可以通过对集合进行增删实现observer的增删操作,notifyObservers方法通过遍历ArrayList,并对遍历的每一个Observer对象调用其update方法,也就是“通知了”每一个观察者!

import java.util.ArrayList;

public class Observerable
{
	private ArrayList<Observer> observers;
	private boolean hasChanged = false;
	
	public Observerable()
	{
		observers = new ArrayList<Observer>();//observers放在构造函数中初始化了!
	}
	protected void setChanged()
	{
		hasChanged = true;
	}
	public void clearChanged()
	{
		hasChanged = false;
	}
	public synchronized void addObserver(Observer obs)
	{
		if(obs==null)
			throw new NullPointerException();
		if(!observers.contains(obs))
			observers.add(obs);
	}
	public synchronized void deleteObserver(Observer obs)
	{
		observers.remove(obs);
	}
	public synchronized void deleteObservers()
	{
		observers.removeAll(observers);
	}
	public synchronized int countObservers()
	{
		return observers.size();
	}
	public void notifyObservers(Object value)
	{
		if(!hasChanged)
			return;
		for(Observer observer : observers)//遍历observers对每个observer执行update方法
			observer.update(this, value);
	}
}


3.来看这个类怎么用吧!

//实现Observer的类

public class Friend implements Observer
{
	private String name=null;
	public Friend(String name)
	{
		this.name = name;
	}
	@Override
	public void update(Observerable observersable, Object value)
	{
		String phoneNum = (String)value;
		System.out.println(this.name + "收到消息:HI!我的手机号已经变成:" + phoneNum);
	}
}

//继承Observerable的类

public class Members extends Observerable
{
	public void addMember(Friend friend)
	{
		super.addObserver(friend);
	}
	public void notifyFriends(String phoneNum)
	{
		super.setChanged();//注意:这里必须先调用setChanged方法,将标记改为true
		super.notifyObservers(phoneNum);
	}
}

//测试类

public class Main
{
	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		Members members = new Members();
		members.addMember(new Friend("zhangsan"));
		members.addMember(new Friend("lisi"));
		members.addMember(new Friend("wangwu"));
		System.out.println(members.countObservers());
		members.notifyFriends("18792503354");
		members.deleteObservers();
		System.out.println(members.countObservers());
	}

}


执行结果:

3
zhangsan收到消息:HI!我的手机号已经变成:18792503354
lisi收到消息:HI!我的手机号已经变成:18792503354
wangwu收到消息:HI!我的手机号已经变成:18792503354
0
好啦,相信到这里大家已经明白了观察者模式了吧,鉴于篇幅我就不在这里尝试jdk提供的Observer啦,大家自己可以试试哦!

                                                                                                                                                                       

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

欢迎转载,转载请标明出处,谢谢!

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值