3、当不想要此主题消息时,取消订阅
4、只要服务号还在,就会一直有人订阅
好了,现在我们来看看观察者模式的类图:
接下来就是代码时间了,我们模拟一个微信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 observers = new ArrayList();
/**
- 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的关系,应该叫回调。
恭喜你学会了观察者模式,上面的观察者模式使我们从无到有的写出,当然了java中已经帮我们实现了观察者模式,借助于java.util.Observable和java.util.Observer。
下面我们使用Java内置的类实现观察者模式:
首先是一个3D彩票服务号主题:
package com.zhy.pattern.observer.java;
import java.util.Observable;
public class SubjectFor3d extends Observable
{
private String msg ;
public String getMsg()
{
return msg;
}
/**
-
主题更新消息
-
@param msg
*/
public void setMsg(String msg)
{
this.msg = msg ;
setChanged();
notifyObservers();
}
}
下面是一个双色球的服务号主题:
尾声
一转眼时间真的过的飞快。我们各奔东西,也各自踏上了自己的旅途,但是即使多年不见,也因为这份情谊我们依旧如从前那般“亲密”。不忘初心方得始终。加油吧,程序员们,在我看来35岁,40岁从来不是危机,只要永远不要忘记自己为何踏上征程!
为了让更多在学习中或者最近要准备面试的朋友们看到这篇文章,希望你们能多多评论,点赞+转发!
再次感谢所有给我提供过题目的朋友们,感谢一路有你!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!