当一个对象状态发生改变,会自动通知依赖对象
观察者模式,需要注意的是区分观察者(Observer)和被观察者(Observable),是被观察者(Observable)的对象状态发生改变时,能自动通知观察者(Observer)对象。
下面通过 微信公众号-公众号用户 来分析:首先被观察者(Observable)对象是:微信公众号;观察者(Observer)对象是:公众号用户。定义被观察者(Observable)对象
/**
* 定义被观察者(Observable)
* 微信公众号
*/
public interface WXPublic {
void register(IUser user);
void unregister(IUser user);
void updateArticle(String article);
}
定义观察者(Observer)对象:
/**
* 观察者(Observer)
* 公众号用户
*/
public interface IUser {
/**
* 公众号文章跟新
*
* @param article
*/
public void publicUpdate(String article);
}
通过接口定义被观察者(Observable)对象和观察者(Observer)对象,下面来实现具体的被观察者(Observable)对象:
/**
* 某一公众号
* 实际被观察者
*/
public class AdvancedWXPublic implements WXPublic {
private List<IUser> mObservers;
private String article;
public AdvancedWXPublic() {
mObservers = new ArrayList<>();
}
@Override
public void register(IUser user) {
if (mObservers != null && !mObservers.contains(user)) {
mObservers.add(user);
}
}
@Override
public void unregister(IUser user) {
if (mObservers != null && mObservers.indexOf(user) >= 0) {
mObservers.remove(user);
}
}
@Override
public void updateArticle(String article) {
if (mObservers != null) {
for (IUser observer : mObservers) {
observer.publicUpdate(article);
}
}
}
public String getArticle() {
return article;
}
public void setArticle(String article) {
this.article = article;
updateArticle(this.article);
}
}
实际的被观察者(Observable)对象就是一个特定的公众号,里面有一个 List<IUser> 用来保存关注了该公众号的用户,当有新的文章跟新时,调用updateArticle 方法自动通知公众号用户,接下来实现具体的观察者(Observer)对象:
/**
* 公众号用户
* 实际观察者
*/
public class User implements IUser {
private String mName;
public User(String name) {
this.mName = name;
}
@Override
public void publicUpdate(String article) {
System.out.println(mName + " : 收到了一篇文章推送《" + article + "》");
}
}
具体的观察者就是一个实际的用户,当公众号的文章跟新时,会自动调用 publicUpdate 方法来获取更新,最后来看看使用:
public class Client {
public static void main(String[] args) {
AdvancedWXPublic advancedWXPublic = new AdvancedWXPublic();
User liang = new User("liang");
User huang = new User("huang");
advancedWXPublic.register(liang);
advancedWXPublic.register(huang);
advancedWXPublic.setArticle("android 进阶艺术");
advancedWXPublic.unregister(liang);
advancedWXPublic.setArticle("第一行代码");
}
}
输出结果为:
WechatIMG447.jpeg
当两个用户都关注该公众号时,公众号文章跟新都能获取到更新,当其中一个不在关注时,就只有一个能获取到更新
上面这种模式称为推模式:公众号有更新,能自动推送更新给用户,还有一种模式称为拉模式:用户能通过公众号来获取更新的文章。修改 IUser,来实现拉模式:
/**
* 微信用户
* 观察者
*/
public interface IUser {
//注意,这里更新方法传过来的参数为 被观察者对象
public void publicUpdate(WXPublic article);
}
继续修改其他,如 AdvancedWXPublic
@Override
public void updateArticle() {
if (mObservers != null) {
for (IUser observer : mObservers) {
//该类需要修改的就是更新时,将自身传过去
observer.publicUpdate(this);
}
}
}
实际的被观察者,当该类对象状态发生改变时,将自身传过去,继续修改实际观察者对象:
/**
* 微信用户
* 实际观察者
*/
public class User implements IUser {
private String mName;
public User(String name) {
this.mName = name;
}
@Override
public void publicUpdate(WXPublic observable) {
//实际观察者,当被观察者对象发生改变时,能获取到被观察者对象
if (observable instanceof AdvancedWXPublic) {
AdvancedWXPublic advancedWXPublic = (AdvancedWXPublic) observable;
//通过被观察者对象,可以拉去更新内容
String article = advancedWXPublic.getArticle();
System.out.println(mName + " : 拉取了一篇更新文章 《" + article + "》");
}
}
}
最后再附上一张类图
观察者模式-UML图.png
网友评论