146°

观察者模式

观察者模式

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

观察模式中的参与者

  • 抽象主题(Subject):它把所有观察者对象的引用保存到一个剧集里,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,以及通知所有观察者
  • 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;当具体主题内部状态发生改变时,通知所有注册过的观察者
  • 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己
  • 具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态保持一致

实现示例

有一个公众号服务,不定时发布一些消息,关注公众号就可以收到推送消息,取消关注就收不到推送消息。

抽象主题 (添加、删除、通知观察者的方法)

package observer;

public interface Subject {

    void registerObserver(Observer observer);

    void removeObserver(Observer observer);

    void notifyObserver(String message);
}

抽象观察者

package observer;

public interface Observer {
    void update(String message);
}

公众号服务

package observer;

import java.util.ArrayList;
import java.util.List;

public class WechatServer implements Subject {
    private List<Observer> observers = new ArrayList<>();

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        if (!observers.isEmpty()) {
            observers.remove(observer);
        }
    }

    @Override
    public void notifyObserver(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }

    public void setInfomation(String s) {
        System.out.println("微信服务更新消息:" + s);
        //消息更新通知所有观察者
        notifyObserver(s);
    }
}

用户

package observer;

public class User implements Observer {
    private String name;

    public User(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        read(message);
    }

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

测试

package observer;

import org.junit.Test;

public class ObserverTest {

    @Test
    public void test(){
        User user = new User("lara");
        User user1 = new User("yolada");
        User user2 = new User("wendy");

        WechatServer wechatServer = new WechatServer();
        wechatServer.registerObserver(user);
        wechatServer.registerObserver(user1);
        wechatServer.registerObserver(user2);
        wechatServer.setInfomation("双十一马上到了");

        wechatServer.removeObserver(user);
        wechatServer.setInfomation("双十一已经结束了");
    }
}

测试结果

微信服务更新消息:双十一马上到了
lara收到推送消息:双十一马上到了
yolada收到推送消息:双十一马上到了
wendy收到推送消息:双十一马上到了
微信服务更新消息:双十一已经结束了
yolada收到推送消息:双十一已经结束了
wendy收到推送消息:双十一已经结束了

本文由【wuyiyi】发布于开源中国,原文链接:https://my.oschina.net/wuyiyi/blog/2877265

全部评论: 0

    我有话说: