观察者模式:定义对象之间一一对多依赖,这样当一个对象改变状态时候,所有依赖他的对象都会收到通知。
适用:当一个事件触发,或者一个状态发生改变,很多相应的地方需要相应这个变化,能避免轮询导致过多耗费资源。
我想了一个哔哩哔哩 视频号被订阅的例子,视频号和订阅的用户都可以进行扩展
源码
package 设计模式.通知者模式;
public class main {
//例子思路
// b站 有视频号 ,大家可以订阅视频号,并且视频号更新可以收到视频号的通知
public static void main(String[] args) {
BiliBili b = new BiliBili();
b.setVideo(new VideoNo("视频号1"));
b.setVideo(new VideoNo("视频号2"));
UserObserver userObserver1 = new UserObserver("用户1");
UserObserver userObserver2 = new UserObserver("用户2");
//用户1订阅视频号1
userObserver1.addVideo(b.getVideo("视频号1"));
//用户1订阅视频号2
userObserver1.addVideo(b.getVideo("视频号2"));
//用户2订阅视频号1
userObserver2.addVideo(b.getVideo("视频号1"));
//视频号更新
b.getVideo("视频号1").upData("视频号1更新了笑话视频");
b.getVideo("视频号2").upData("视频号2更新了吃播视频");
//视频号和用户都可以动态添加
}
}
package 设计模式.通知者模式;
import sun.jvm.hotspot.opto.HaltNode;
import java.util.HashMap;
import java.util.Map;
public class BiliBili {
//B栈所有视频号
Map<String,Video> videoMap = new HashMap<>();
//获取某一个视频号
public Video getVideo(String videoName){
return videoMap.get(videoName);
}
//放入一个视频号
public void setVideo(Video video){
videoMap.put(video.getVideoName(),video);
}
}
package 设计模式.通知者模式;
public interface Observer {
//订阅某个视频号
void addVideo(Video v);
//删除订阅某个视频号
void delVideo(Video v);
//接受通知
void printData(String data);
//返回订阅者名称
String getName();
}
package 设计模式.通知者模式;
/**
* 视频号类
*/
public interface Video {
//添加订阅的人
void addUser(Observer user);
//减少订阅的人
void delUser(Observer user);
//更新视频
void upData(String data);
//获取视频号名称
String getVideoName();
}
package 设计模式.通知者模式;
import java.util.HashMap;
import java.util.Map;
public class UserObserver implements Observer {
//订阅视频列表
Map<String,Video> videoMap;
//订阅人姓名
String userName;
public UserObserver(String userName) {
this.userName = userName;
videoMap = new HashMap<>();
}
@Override
public void addVideo(Video v) {
v.addUser(this);
videoMap.put(v.getVideoName(),v);
}
@Override
public void delVideo(Video v) {
v.delUser(this);
videoMap.remove(v.getVideoName());
}
@Override
public void printData(String data) {
System.out.println("订阅人"+userName+"接收到了消息:"+data);
}
@Override
public String getName() {
return userName;
}
}
package 设计模式.通知者模式;
import java.util.HashMap;
import java.util.Map;
public class VideoNo implements Video{
//需要通知的订阅者
Map<String,Observer> observerMap;
//视频号名称
String name;
public VideoNo(String name) {
this.name = name;
this.observerMap = new HashMap<>();
}
@Override
public void addUser(Observer user) {
observerMap.put(user.getName(),user);
}
@Override
public void delUser(Observer user) {
observerMap.remove(user.getName());
}
@Override
public void upData(String data) {
for (Observer value : observerMap.values()) {
value.printData(data);
}
}
@Override
public String getVideoName() {
return name;
}
}