观察者模式--模拟3D彩票公众号
一 观察者模式定义:
观察者模式又叫发布-订阅模式,它定义了一种一对多的依赖关系,多个观察者对象可同时监听某一主题对象,当该主题对象状态发生变化时,相应的所有观察者对象都可收到通知。
二 观察者模式类图
三 观察者模式角色划分
1)主题,抽象类或者接口
2)具体主题
3)观察者
4)具体观察者
四 观察者模式实例
1)、服务号就是主题,业务就是推送消息
2)、观察者只需要订阅主题,只要有新的消息就会送来
3)、当不想要此主题消息时,取消订阅
4)、只要服务号还在,就会一直有人订阅
本实例模拟3D彩票服务,和部分订阅者。
1.主题接口和观察者接口
/**
* 主题接口,所有的主题必须实现此接口
*/
public interface Subject
{
/**
* 注册一个观察着
*
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 移除一个观察者
*
* @param observer
*/
public void removeObserver(Observer observer);
/**
* 通知所有的观察着
*/
public void notifyObservers();
}
2.所有观察者都需要实现这个接口
public interface Observer {
public void update(String msg);
}
3.3D服务号的实现
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();
}
}
4.模拟两个使用者
4.1第一个使用者
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 + ", 我要记下来。");
}
}
4.2第二个使用者
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 + "我要告诉舍友们。");
}
}
服务号中维护了所有向它订阅消息的使用者,当服务号有新消息时,通知所有的使用者。整个架构是一种松耦合,主题的实现不依赖与使用者,当增加新的使用者时,主题的代码不需要改变;使用者如何处理得到的数据与主题无关。
5.测试代码
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" );
}
}
五 观察者模式的优缺点
观察者模式优点
抽象主题只依赖于抽象观察者
观察者模式支持广播通信
观察者模式使信息产生层和响应层分离
观察者模式缺点
如一个主题被大量观察者注册,则通知所有观察者会花费较高代价
如果某些观察者的响应方法被阻塞,整个通知过程即被阻塞,其它观察者不能及时被通知
实例链接:https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/observer