每个人应该都订阅了不少微信公众号,那你有没有注意到微信公众号的消息呢?你订阅的公众号号主每发布一篇文章,你都会主动的接收到文章的推送,并不需要你点开每个订阅的公众号一一查看有没有更新,是不是觉得有点意思?感兴趣?那就接着往下看吧,因为接下来我们要模拟公众号群发的场景。
要模拟公众号群发,首先需要简单的了解一下公众号的特点,对于公众号的特点,我总结了以下三点:
- 每个公众号会有多名订阅者,公众号跟订阅者在某种层面上是一对多的关系
- 只有订阅者才能在公众号发布新文章时,会及时接收到推送通知,没有订阅公众号的阅读者不会接收到文章推送通知。
- 每个订阅者都依赖于公众号号主,只有公众号号主发布文章,订阅者才有文章查看
现在业务场景我们大概知道了,那就开始动手编写我们的业务吧,我们先从公众号号主开始。
对于公众号号主,我们先理解一下公众号特点的第二点:只有订阅者才能在公众号发布新文章时,会及时接收到推送通知,没有订阅公众号的阅读者不会接收到文章推送通知。这个特点说明在公众号号主这边维护者订阅者的列表,在每次发布文章时会通知列表中的每一个订阅者告诉他们有新文章了。如果号主没有订阅者列表,那怎么知道需要通知哪些人呢?对于这个订阅者列表,号主肯定有增删的权利,毕竟这个公众号你说了算。根据上面分析的,我们给号主做出一个抽象,我们建立一个抽象的Author
类。Author
类具体设计如下:
/**
* 号主抽象类
*/
public interface Author {
// 添加关注者
void addReader(Reader reader);
// 删除关注者
void deleteReader(Reader reader);
// 通知关注者
void notifyReader();
// 写文章
void writeArticle(String article);
}
在我们的场景中号主主要有添加订阅者、删除订阅者、通知订阅者和写文章的功能,号主有了,接下来就是我们的订阅者,订阅者在我们的场景中就比较简单了,只有一个阅读的功能,我们定义一个阅读者抽象类Reader
,Reader
类的具体设计如下:
/**
* 阅读者接口
*/
public interface Reader {
// 阅读文章
void reader(String authorName,String article);
}
号主和阅读者的接口都定义好了,下面我们就需要真正的号主和订阅者了。我们建立我们第一个号主平头哥PingtougeAuthor
,PingtougeAuthor
类的设计如下:
/**
* @author 平头哥
* @title: PingtougeAuthor
* @projectName observer
* @description: 号主平头哥
* @date 2019/9/1817:50
*/
public class PingtougeAuthor implements Author{
// 订阅者列表
private Vector<Reader> readers ;
// 作者名称
private String name;
// 文章
private String article;
public PingtougeAuthor(String name){
this.name = name;
this.readers = new Vector<>();
}
/**
* 添加关注者
* @param reader
*/
@Override
public void addReader(Reader reader) {
if (readers.contains(reader)) return;
readers.add(reader);
}
/**
* 移除关注者
* @param reader
*/
@Override
public void deleteReader(Reader reader) {
readers.remove(reader);
}
/**
* 通知关注者
*/
@Override
public void notifyReader() {
for (Reader reader:readers){
reader.reader(name,article);
}
}
/**
* 写文章
* @param article
*/
@Override
public void writeArticle(String article){
this.article = article;
notifyReader();
}
}
我们在建立王山、张三、李四三个订阅者,他们的具体设计如下:
/**
* 订阅者王山
*/
public class WangSanReader implements Reader{
private String name;
public WangSanReader(String name){
this.name = name;
}
@Override
public void reader(String authorName,String article) {
System.out.println(name+" 阅读了 "+authorName+" 发布的 "+article+" 文章");
}
}
/**
* 订阅者张三
*/
public class ZhangsanReader implements Reader{
private String name;
public ZhangsanReader(String name){
this.name = name;
}
@Override
public void reader(String authorName,String article) {
System.out.println(name+" 阅读了 "+authorName+" 发布的 "+article+" 文章");
}
}
/**
* 订阅者者李四
*/
public class LiSiReader implements Reader{
private String name;
public LiSiReader(String name){
this.name = name;
}
@Override
public void reader(String authorName,String article) {
System.out.println(name+" 阅读了 "+authorName+" 发布的 "+article+" 文章");
}
}
号主和订阅者都有了,万事俱备只欠东风,那我们就来进行我们第一次场景模拟,在这次模拟中,订阅者张三、王山订阅了平头哥的公众号,李四没有订阅平头哥的公众号。按照我们的设想平头哥发布文章时,张三、王山可以接收到文章推送通知,李四不会接收到文章推送通知。编写我们的第一个模拟类:
public class App {
public static void main(String[] args) {
PingtougeAuthor pingtougeAuthor = new PingtougeAuthor("平头哥");
Wa