首页 > 其他 > 详细

设计模式 观察者模式

时间:2014-04-20 19:55:26      阅读:615      评论:0      收藏:0      [点我收藏+]

继续设计模式的文章,今天给大家带来观察者模式。

先来看看观察者模式的定义:

定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。

好了,对于定义的理解总是需要实例来解析的,如今的微信服务号相当火啊,下面就以微信服务号为背景,给大家介绍观察者模式。

看一张图:

bubuko.com,布布扣

其中每个使用者都有上图中的3条线,为了使图片清晰省略了。

如上图所示,服务号就是我们的主题,使用者就是观察者。现在我们明确下功能:

1、服务号就是主题,业务就是推送消息

2、观察者只需要订阅主题,只要有新的消息就会送来

3、当不想要此主题消息时,取消订阅

4、只要服务号还在,就会一直有人订阅

好了,现在我们来看看观察者模式的类图:

bubuko.com,布布扣

接下来就是代码时间了,我们模拟一个微信3D彩票服务号,和一些订阅者。

首先开始写我们的主题接口,和观察者接口:

package com.zhy.pattern.observer;

/**
 * 主题接口,所有的主题必须实现此接口
 * 
 * @author zhy
 * 
 */
public interface Subject
{
	/**
	 * 注册一个观察着
	 * 
	 * @param observer
	 */
	public void registerObserver(Observer observer);

	/**
	 * 移除一个观察者
	 * 
	 * @param observer
	 */
	public void removeObserver(Observer observer);

	/**
	 * 通知所有的观察着
	 */
	public void notifyObservers();

}

package com.zhy.pattern.observer;

/**
 * @author zhy 所有的观察者需要实现此接口
 */
public interface Observer
{
	public void update(String msg);

}

接下来3D服务号的实现类:

package com.zhy.pattern.observer;

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

public class ObjectFor3D implements Subject
{
	private List<Observer> observers = new ArrayList<Observer>();
	/**
	 * 3D彩票的号码
	 */
	private String msg;

	@Override
	public void registerObserver(Observer observer)
	{
		observers.add(observer);
	}

	@Override
	public void removeObserver(Observer observer)
	{
		int index = observers.indexOf(observer);
		if (index >= 0)
		{
			observers.remove(index);
		}
	}

	@Override
	public void notifyObservers()
	{
		for (Observer observer : observers)
		{
			observer.update(msg);
		}
	}

	/**
	 * 主题更新消息
	 * 
	 * @param msg
	 */
	public void setMsg(String msg)
	{
		this.msg = msg;
		
		notifyObservers();
	}

}

模拟两个使用者:

package com.zhy.pattern.observer;

public class Observer1 implements Observer
{

	private Subject subject;

	public Observer1(Subject subject)
	{
		this.subject = subject;
		subject.registerObserver(this);
	}

	@Override
	public void update(String msg)
	{
		System.out.println("observer1 得到 3D 号码  -->" + msg + ", 我要记下来。");
	}

}

package com.zhy.pattern.observer;

public class Observer2 implements Observer
{
	private Subject subject ; 
	
	public Observer2(Subject subject)
	{
		this.subject = subject  ;
		subject.registerObserver(this);
	}
	
	@Override
	public void update(String msg)
	{
		System.out.println("observer2 得到 3D 号码 -->" + msg + "我要告诉舍友们。");
	}
	
	

}
可以看出:服务号中维护了所有向它订阅消息的使用者,当服务号有新消息时,通知所有的使用者。整个架构是一种松耦合,主题的实现不依赖与使用者,当增加新的使用者时,主题的代码不需要改变;使用者如何处理得到的数据与主题无关;

最后看下测试代码:

package com.zhy.pattern.observer.test;

import com.zhy.pattern.observer.ObjectFor3D;
import com.zhy.pattern.observer.Observer;
import com.zhy.pattern.observer.Observer1;
import com.zhy.pattern.observer.Observer2;
import com.zhy.pattern.observer.Subject;

public class Test
{
	public static void main(String[] args)
	{
		//模拟一个3D的服务号
		ObjectFor3D subjectFor3d = new ObjectFor3D();
		//客户1
		Observer observer1 = new Observer1(subjectFor3d);
		Observer observer2 = new Observer2(subjectFor3d);

		subjectFor3d.setMsg("20140420的3D号码是:127" );
		subjectFor3d.setMsg("20140421的3D号码是:333" );
		
	}
}

输出结果:
observer1 得到 3D 号码  -->20140420的3D号码是:127, 我要记下来。
observer2 得到 3D 号码 -->20140420的3D号码是:127我要告诉舍友们。
observer1 得到 3D 号码  -->20140421的3D号码是:333, 我要记下来。
observer2 得到 3D 号码 -->20140421的3D号码是:333我要告诉舍友们。

对于JDK或者Andorid中都有很多地方实现了观察者模式,比如XXXView.addXXXListenter , 当然了 XXXView.setOnXXXListener不一定是观察者模式,因为观察者模式是一种一对多的关系,对于setXXXListener是1对1的关系,应该叫回调。

恭喜你学会了观察者模式,当然了明白了一个模式,不一定能够很好的去融入到自己的代码,且有些需求是需要在模式的基础上做出一些改变的,比如上面的代码只能只能实现一个观察者对应于一个主题,正在的微信主题和使用者应该是对多的关系,且每个主题推动的东西不同(文本,图片,视频等)。以后将会在观察者模式的基础上针对多对多,以及推送不同的消息写一篇博客做分析。


如果你觉得这篇文章对你有用,赞一个吧~嘿嘿


设计模式 观察者模式,布布扣,bubuko.com

设计模式 观察者模式

原文:http://blog.csdn.net/lmj623565791/article/details/24179699

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!