自从有了微信公众号后,关注了某个公众号基本每天都有新的文章推送的通知,我们可以很方便的进行查阅,了解最新的资讯,什么老美放大水、什么中东又暴乱了,第一时间就知道了,而这里的关注和通知的行为其实有点类似观察者模式的观察者。用户关注公众号,公众号(被观察者)更新文章通知所有用户(观察者)。
观察者模式是什么?
观察者模式(Observer Pattern)它属于行为模式。定义了一种一对多依赖的系,使用每当一个对象改变状态,则所有的依赖于它的对象都会得到通知并被自动更新。
角色:
ObServer(观察者):负责监听消息,当收到被观察者的状态改变时通知自己,做出更新动作。
ConcreteObServer(具体观察者):具体实现观察者的实现。
Subject(被观察者):负责将所有的观察者保存在一个集合里,并且支持动态增减。
ConcreteSubject(具体被观察者):具体的被观察者的实现,当内部发生改变时,通知所有的观察者。
观察者模式可以干嘛?
观察者模式主要解决是一对多或者多对多之间依赖通知的问题。通过一个监听的中间件,当被观察者发生改变,去通知所有观察者,以达到观察者与被观察关系解耦,非直接依赖关系,并且双方有利于拓展。
优点:
单一职责:由于观察者、被观察者、的职责单一,所有符合该规则。
开闭原则:支持对新的观察者和被观察者的增加。
低耦合:观察者、被观察者双方都没有直接的联系,而且通过消息的通知进行。
缺点:
效率:在开发上需要开发各个角色的功能,在业务流程上都是通过消息进行通知去触发,如果数据量比较大可能会效率较低。
个人理解:
观察者模式就类似于我们(观察者)订阅(监听)微信公众号(被观察者),微信公众号发布文章通知到我们,我们查阅。
观察者模式类图
/**
* @Auther: csh
* @Date: 2020/6/11 11:03
* @Description:抽象观察者(ObServer)
*/
public abstract class ObServer {
protected Subject subject;
public abstract void update(String message);
}
/**
* @Auther: csh
* @Date: 2020/6/11 11:04
* @Description:被观查者
*/
public class Subject {
protected List<ObServer> obServerList = new ArrayList <ObServer>();
private String message;
//添加订阅者
public void attach(ObServer obServer){
obServerList.add(obServer);
}
//删除订阅者
public void del(ObServer obServer){
if(null!=obServer){
obServerList.remove(obServer);
}
}
//通知所有订阅者
public void notifyAllObservers(String message){
for (ObServer obServer : obServerList) {
obServer.update(message);
}
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
/**
* @Auther: csh
* @Date: 2020/6/11 11:12
* @Description:用户(具体观察者)
*/
public class User extends ObServer {
private String name;
public User(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println("用户:"+name+"收到通知:"+message);
}
}
/**
* @Auther: csh
* @Date: 2020/6/11 11:18
* @Description:观察者模式,用户关注的公众号后,公众号更新文章通知所有用户。
*/
public class Client {
public static void main(String[] args) {
//关注【技术趋势】公众号
Subject jsqs = new Subject();
//用户
User user = new User("小明");
User user2 = new User("小红");
User user3 = new User("小绿");
//订阅公众号
jsqs.attach(user);
jsqs.attach(user2);
jsqs.attach(user3);
//公众号更新文章
jsqs.notifyAllObservers("观察者模式");
}
}
结果
用户:小明收到通知:观察者模式
用户:小红收到通知:观察者模式
用户:小绿收到通知:观察者模式
最后
观察者模式主要解决是一对多或者多对多之间依赖通知的问题,在redis订阅、邮件订阅、消息通知等者借鉴该模式的思想,所以该模式应用于实际工作中非常广泛,当然若日常开发遇到,非必须的情况下直接用已成熟的开源框架为多。
开源场景:
java
java.util.Observer
java.util.Observable