观察者模式

定义:
在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。

可以理解为报纸配送员配送报纸,订阅报纸就会每天收到报纸,不订阅就收不到报纸了。
模式结构图:
在这里插入图片描述
举个例子:配送员配送报纸
首先定义一个报亭接口:

public interface Newsstand{
	//这两个方法都需要一个观察者作为变量,用来注册或者被删除的
    void registerObsercer(News n);
    void removeObserver(News n);
    //当主题状态被改变时,会调用这个方法,通知所有观察者 
    void notifyObserver();
}

配送员实现接口

public class Courier implements Newsstand {
    private List<News> list;
    private String message;
    public Courier(){
        list = new ArrayList<News>();
    }

    @Override
    public void registerObsercer(News n) {
        list.add(n);
    }

    @Override
    public void removeObserver(News n) {
        if(!list.isEmpty()){
            list.remove(n);
        }
    }

    @Override
    public void notifyObserver() {
        for(int i=0;i<list.size();i++){
            News observer = list.get(i);
            news.update(message);
        }
    }

    public void setInfomation(String s){
        this.message = s;
        System.out.println("最新消息:"+s);
        notifyObserver();
    }
}

定义新闻接口

public interface News {
	//需要发送的消息内容
    void update(String message);
}

订阅者实现接口

public class User implements News {
    private String name;
    private String message;

    public User(String name){
        this.name = name;
    }
    @Override
    public void update(String message) {
        this.message = message;
        read();
    }
    public void read(){
        System.out.println(name + " 收到推送消息: " + message);
    }
}

场景测试

public class Client {
    public static void main(String[] args) {
        Courier server = new Courier();
        //创建人员
        News zhangsan = new User("zhangsan");
        News lisi = new User("lisi");
        News wangwu = new User("wangwu");
        //注册多个订阅者
        server.registerObsercer(zhangsan);
        server.registerObsercer(lisi);
        server.registerObsercer(wangwu);
        //发布消息
        server.setInfomation("程序员不用加班啦!!");

        System.out.println("----------------------------------------------");
        //张三退出订阅,接收不到消息
        server.removeObserver(zhangsan);
        //发布消息
        server.setInfomation("上一条是谣言!!!");
    }
}

输出结果:
在这里插入图片描述
总结:

  1. 这个模式是松偶合的。改变主题或观察者中的一方,另一方不会受到影像。
  2. JDK中也有自带的观察者模式。但是被观察者是一个类而不是接口,限制了它的复用能力。
  3. 在JavaBean和Swing中也可以看到观察者模式的影子。

版权声明:本文为weixin_44564365原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。