共计 2308 个字符,预计需要花费 6 分钟才能阅读完成。
<!– more –>
本文原创地址,我的博客:https://jsbintask.cn/2019/04/15/designpattern/observer/(食用效果最佳),转载请注明出处!
前言
观察者模式定义了对象间的一种一对多依赖关系,当一个对象状态发生改变时,观察者们都可以做出相应的更新,使得系统更易于扩展!代码地址:https://github.com/jsbintask22/design-pattern-learning
案例
小丽长得很漂亮,” 天生丽质难自弃 ”, 是一个不折不扣的 ” 女神 ”。
小丽身边有很多”备胎“,他们通过各种方式添加了小丽的微信,“小豪,小吴”都是其中之一。
小丽总是会在朋友圈发布自己的各种生活状态。
”备胎们“总是及时并且积极地和女神互动!
小丽发现”备胎“小豪不爱互动了,于是删除了“备胎”小豪的微信。
小豪发现自己看不了女神动态了。最终死心!
小丽认识了新“备胎”小李,于是小李也添加了女神微信。
小丽发布自己的朋友圈动态,小李也开始了互动!
上面这个过程我们可以抽象出来两个主题,女神小丽, 备胎小豪,小吴,小李,我们用代码模拟这个追女神的过程。
代码实现
V1.0
Beauty 代表女神,LittleBoy 表示备胎,他们时刻在关注着女神的朋友圈,希望获得互动,代码实现如下:
public class App {
public static void main(String[] args) throws Exception{
Beauty beauty = new Beauty();
// 成功添加了女神微信
LittleBoy littleBoy = new LittleBoy(beauty);
// 开始查看女神朋友圈
littleBoy.start();
// 5s 后,女神发布了朋友圈。
Thread.sleep(5000L);
beauty.publishWechat();
System.in.read();
}
}
运行结果如下:嗯!似乎很完美!美中不足的是好像 LittleBoy 的 run 方法一直在轮询查看女神朋友圈,它没办法做自己的事情了:这样下去很快他就会失去和女神互动的耐心!所以我们稍微修改下,让这段代码看起来更加”智能”。
V2.0
为了不让 LittleBoy 一直轮询查看女神状态,我们可以修改为女神主动推送她的状态给“备胎们”,这样他们就可以去做其他事情了!
public class App {
public static void main(String[] args) throws Exception{
Beauty beauty = new Beauty();
LittleBoy littleBoy = new LittleBoy();
// 添加女神微信
beauty.littleBoy = littleBoy;
// 发布动态
beauty.publishWechat();
}
}
嗯!这样一来就智能多了!女神更新朋友圈后主动推送消息给备胎!备胎不用死守着女神的朋友圈,而是收到消息后自动去查看。所以他们的关系是这样了:但是,现在又有一个新问题!这段代码好像显得不够面向对象,不够专业。
女神如果想要新加一个舔狗,就要动女神的逻辑代码。
新加了一个备胎之后,不知道如何把自己的动态分享给他(例如上面的 active 方法,可能“新备胎”没有)。
备胎突然舔不动了怎么办了,他不想再收到女神动态了!
既然这样,我们把这段代码修改下,让它变得“灵活”,更加“面向对象”些!
V3.0
既然要灵活,面向对象。我们这么处理:将女神抽象为一个接口,并且她要能够删除备胎,添加备胎,通知备胎。同时我们将备胎抽象为一个接口,他能够在收到女神通知后及时做出反应!Beauty:LittleBoy: 它们分别有一个实现:BeautyImpl 和 LittleBoyImpl: 测试代码:
public class App {
public static void main(String[] args) {
Beauty beauty = new BeautyImpl();
LittleBoy boy1 = new LittleBoyImpl(“ 小豪 ”);
LittleBoy boy2 = new LittleBoyImpl(“ 小吴 ”);
// 添加两个备胎
beauty.addLittleBoy(boy1);
beauty.addLittleBoy(boy2);
// 发布朋友圈
beauty.publishWechat(“ 最美的不是下雨天,是曾和你一起躲过雨的屋檐!”);
// 删除备胎 1,并且新添加了备胎 3
beauty.removeLittleBoy(boy1);
beauty.addLittleBoy(msg -> {
System.out.println(” 小李:哎哟,不错哦!”);
});
// 再次发布朋友圈
beauty.publishWechat(“ 哪里有彩虹告诉我。。。”);
}
}
嗯!通过面向接口编程完美的解决了上面的问题,现在女神这个类已经变得非常灵活了,仔细观察,我们已经把我们上面的说的案例完全实现!现在它们的关系是这样的:
扩展
观察者模式这种发布与订阅的思想使用的非常广泛,基本各个框架,思想都能看到它的身影,而 jdk 中也已经抽象了观察与被观察者:java.util.Observer 表示观察者:java.util.Obserable 表示被观察者(例如上面的女神):然后美中不足的是,jdk 把 Observable 设计成了一个类,这并不利于扩展!当然我们仍然可以自己实现接口,就像上面所做的。
总结
我们从观察者模式特点入手,通过一个案例,一步一步完善了观察着的写法,特点!组后介绍了 jdk 总已有的实现!
关注我,这里只有干货!
同系列文章:从未这么明白的设计模式(一):单例模式