通俗易懂的java设计模式(3)-观察者设计模式

Source

什么是观察者设计模式

观察者模式主要应用在对象存在一对多关系的情况下,那么如果一个对象,依赖于另一个对象,那个被依赖的对象一旦被修改,依赖于他的那个对象也会被观察者所告知。

观察者模式又被称作为发布-订阅模式,另一种解释:多个观察者同时监听某个主题,当这个主题被修改时,会告知所有的观察者,这样观察者就能主动地更新自己(我觉得用发布订阅更好理解):

  • 观察者模式中的几个重要角色:

    • 抽象主题:提供一个观察者对象的集合,以及增加删除观察者对象的方法,还有通知所有观察者的抽象方法。
    • 具体主题继承上面的抽象主题,实现通知方法,当具体主题的状态发生了变化时,就会通知所有观察者,这个类根据具体项目来定。
    • 抽象观察者:一个抽象类或者接口,有一个接到具体主题通知后的更新自己的方法
    • 具体观察者:实现抽象观察者中的更新自己的方法。
  • 需要解决的问题

    • 如何获取到对象的状态发生改变
    • 怎么设计这个观察者,去通知其他对象

观察者设计模式的优缺点

  • 优点:

    • 在观察者和被观察者(即具体主题)之间建立了一种抽象的耦合(观察者和被观察者可以独立修改,互不影响)
    • 自己建立了一种触发机制
  • 缺点:

    • 观察者过多时,发布通知会消耗大量时间

简单的代码实现

  • 抽象观察者
/**
 * 抽象观察者中定义更新自己的方法
 */
public interface Observer {
    
      
    void update(String message);
}
  • 具体观察者

这里以微博为例,所有的微博用户就是观察者

public class WeiboUser implements Observer{
    
      
    private String name;
    public WeiboUser(String name) {
    
      
        this.name = name;
    }

    @Override
    public void update(String message) {
    
      
        System.out.println(name+"关注的"+message+"更新了");
    }
}
  • 抽象主题
public interface Subject {
    
      
    /**
     * 增加观察者
     */
    void addObserver(Observer observer);
    /**
     * 删除观察者
     */
    void deleteObserver(Observer observer);
    /**
     * 通知所有观察者的方案
     */
    void notify(String message);
}
  • 具体主题

既然微博用户是观察者,那么这里的具体主题,就是他们关注的某某明星

public class WeiboSubject implements Subject{
    
      
    /**
     * 关注这个明星的所有微博用户
     */
    List<Observer> users = new ArrayList<>();
    @Override
    public void addObserver(Observer observer) {
    
      
        users.add(observer);
    }

    @Override
    public void deleteObserver(Observer observer) {
    
      
        users.remove(observer);
    }

    @Override
    public void notify(String message) {
    
      
        for (Observer user : users) {
    
      
            //将消息传给每一个观察者
            user.update(message);
        }
    }
}
  • 测试
public class TestObserver {
    
      
    public static void main(String[] args) {
    
      
        //微博明星账号
        WeiboSubject weiboSubject = new WeiboSubject();
        //微博用户账号
        WeiboUser weiboUser = new WeiboUser("ikun1");
        WeiboUser weiboUser1 = new WeiboUser("ikun2");
        WeiboUser weiboUser2 = new WeiboUser("ikun3");
        //用户订阅了明星
        weiboSubject.addObserver(weiboUser);
        weiboSubject.addObserver(weiboUser1);
        weiboSubject.addObserver(weiboUser2);
        //明星更新,用户接到通知
        weiboSubject.notify("蔡徐坤");
    }
}

测试结果
在这里插入图片描述