订阅发布最常见的就是在公众号的订阅,用户订阅了公众号后,公众号发布消息时就能收到。其实他相当于设计模式中的观察者模式
用户首先对感兴趣的服务进行订阅,该服务在发送消息时会将消息发送至所有订阅的用户。
使用java实现的版本
首先定义下接口,再对其进行实现。
public interface Service {
boolean addSubscribe(Observice observice); // 增加订阅者
boolean removeSubscribe(Observice observice); // 删除订阅者
void push(Object o); // 推送消息
}
这是一个服务的接口,声明了3个主要的方法,分别是增加订阅,删除订阅,以及推送消息。
public interface Observice {
void gotIt(Object s); // 收到消息后的动作
String getId();
String getName();
}
这个接口用来作为用户的接口,提供获取Id,name以及消息订阅后的动作。
下面是消息服务的实现,在收到订阅后根据id放到map里,然后根据id删除。
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MessageService implements Service {
private static Map<String,Observice> observerMap = new ConcurrentHashMap<>();
@Override
public boolean addSubscribe(final Observice observice) {
observerMap.put(observice.getId(),observice);
System.out.println(String.format("用户Id %s 姓名 %s 插入成功 ", observice.getId(), observice.getName()));
return true;
}
@Override
public boolean removeSubscribe(final Observice observice) {
if (observerMap.get(observice.getId()) == null){
System.out.println(String.format("用户Id %s 姓名 %s 不存在 移除失败", observice.getId(), observice.getName()));
return false;
}
observerMap.remove(observice.getId());
System.out.println(String.format("用户Id %s 姓名 %s 已经移除 ", observice.getId(), observice.getName()));
return true;
}
@Override
public synchronized void push(Object S) {
if (null == S) return;
observerMap.forEach((k,v)-> v.gotIt(S));// 推送时采用轮训推送
System.out.println("所有消息推送完毕");
}
下面是用户接口的实现,在收到消息后只是简单的打印了出来
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class VipUser implements Observice {
private String id;
private String username;
@Override
public void gotIt(Object s) {
System.out.print("收到了推送:\t");
System.out.println(s);
}
@Override
public String getId() {
return this.id;
}
@Override
public String getName() {
return this.username;
}
}
在编写完后对整个流程进行测试
public static void main(String[] args) {
Service service = new MessageService();
Observice user1 = new VipUser("1","小李");
Observice user2 = new VipUser("2","小王");
Observice user3 = new VipUser("3","小张");
// 每个用户都进行订阅
service.addSubscribe(user1);
service.addSubscribe(user2);
service.addSubscribe(user3);
service.push("大家好,这是第一条推送");// 推送消息
service.removeSubscribe(user2);
service.removeSubscribe(user2);// 移除两次,会提示移除失败。
service.push("大家好,这条推送没小王");
}
结果如下
用户Id 1 姓名 小李 插入成功
用户Id 2 姓名 小王 插入成功
用户Id 3 姓名 小张 插入成功
收到了推送: 大家好,这是第一条推送
收到了推送: 大家好,这是第一条推送
收到了推送: 大家好,这是第一条推送
所有消息推送完毕
用户Id 2 姓名 小王 已经移除
用户Id 2 姓名 小王 不存在 移除失败
收到了推送: 大家好,这条推送没小王
收到了推送: 大家好,这条推送没小王
所有消息推送完毕
通过这个小栗子可以初步的了解这种模式的设计,这样可以使用户和服务进行松耦合,用户可以随意的选择服务进行订阅,消息也可以精准的推送。