实际业务开发过程中,业务逻辑可能非常复杂,核心业务 + N 个子业务。如果都放到一块儿去做,代码可能会很长,耦合度不断攀升,维护起来也麻烦,甚至头疼。还有一些业务场景不需要在一次请求中同步完成,比如邮件发送、短信发送等。
就比如工作中实际遇到的,报告生成存库了,后面开发的时候又要加功能需要发送短信通知别人, 如果直接在报告存库的代码下面再写一百多行发送短信的代码,太臃肿了, 报告存库的功能和发短信的功能两者是独立的,没有必要把代码写在一堆里, 这个时候就可以用观察者模式.
但是我看完下面的代码好像还是不会用.
观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。
在观察者模式中有如下角色:
观察者模式这种发布-订阅的形式我们可以拿微信公众号来举例,假设微信用户就是观察者,微信公众号是被观察者,有多个的微信用户关注了程序猿这个公众号,当这个公众号更新时就会通知这些订阅的微信用户。好了我们来看看用代码如何实现:
里面定义了一个更新的方法:
- public interface Observer {
- public void update(String message);
- }
微信用户是观察者,里面实现了更新的方法:
- public class WeixinUser implements Observer {
- // 微信用户名
- private String name;
- public WeixinUser(String name) {
- this.name = name;
- }
- @Override
- public void update(String message) {
- System.out.println(name + "-" + message);
- }
-
-
- }
抽象主题,提供了attach、detach、notify三个方法:
- public interface Subject {
- /**
- * 增加订阅者
- * @param observer
- */
- public void attach(Observer observer);
- /**
- * 删除订阅者
- * @param observer
- */
- public void detach(Observer observer);
- /**
- * 通知订阅者更新消息
- */
- public void notify(String message);
- }
微信公众号是具体主题(具体被观察者),里面存储了订阅该公众号的微信用户,并实现了抽象主题中的方法:
- public class SubscriptionSubject implements Subject {
- //储存订阅公众号的微信用户
- private List
weixinUserlist = new ArrayList(); -
- @Override
- public void attach(Observer observer) {
- weixinUserlist.add(observer);
- }
-
- @Override
- public void detach(Observer observer) {
- weixinUserlist.remove(observer);
- }
-
- @Override
- public void notify(String message) {
- for (Observer observer : weixinUserlist) {
- observer.update(message);
- }
- }
- }
- public class Client {
- public static void main(String[] args) {
- SubscriptionSubject mSubscriptionSubject=new SubscriptionSubject();
- //创建微信用户
- WeixinUser user1=new WeixinUser("杨影枫");
- WeixinUser user2=new WeixinUser("月眉儿");
- WeixinUser user3=new WeixinUser("紫轩");
- //订阅公众号
- mSubscriptionSubject.attach(user1);
- mSubscriptionSubject.attach(user2);
- mSubscriptionSubject.attach(user3);
- //公众号更新发出消息给订阅的微信用户
- mSubscriptionSubject.notify("刘望舒的专栏更新了");
- }
- }
结果
- 杨影枫-刘望舒的专栏更新了
- 月眉儿-刘望舒的专栏更新了
- 紫轩-刘望舒的专栏更新了
解除耦合,让耦合的双方都依赖于抽象,从而使得各自的变换都不会影响另一边的变换。
在应用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。