观察者模式 - 行为
一、概述
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
二、步骤
核心:就是把所有观察者都存在一个公共的变量里面,然后某一个状态发送变更时,从公共的变量里面取出所有观察者,然后调用观察者预先实现的方法。
/** * 观察者模式 * * 场景:当天气更新以后,动态的去通知所有关注天气预报的人 * * <p> * 参考:https://www.runoob.com/design-pattern/observer-pattern.html * * @author zls * @date 2020/6/18 */ public class ObserverDemo { public static void main(String[] args) { WeatherSubject weatherSubject = new WeatherSubject(); new Male("高露", weatherSubject); new Female("黄梦莹", weatherSubject); weatherSubject.setState("天气晴"); System.out.println("-------- 天气预报改变了自动的去通知 -------"); weatherSubject.setState("天气小雨"); } } /** * 被观察者接口 */ @Data abstract class Person { // 姓名 public String name; // 持有天气预报(关注的都是同一个天气预报) protected WeatherSubject weatherSubject; // 接收消息 public abstract void receive(); } /** * 创建实体观察者类 */ class Male extends Person { public Male(String name, WeatherSubject weatherSubject) { this.name = name; this.weatherSubject = weatherSubject; this.weatherSubject.attach(this); } @Override public void receive() { System.out.println( this.name + "(男)接收到了天气预报:" + weatherSubject.getState()); } } class Female extends Person { public Female(String name, WeatherSubject weatherSubject) { this.name = name; this.weatherSubject = weatherSubject; this.weatherSubject.attach(this); } @Override public void receive() { System.out.println( this.name + "(女)接收到了天气预报:" + weatherSubject.getState()); } } /** * 主题 */ class WeatherSubject { private List<Person> persons = new ArrayList<>(); // 天气状态 private String state; public String getState() { return state; } public void setState(String state) { this.state = state; notifyAllObservers(); } /** * 将所有关注天气预报的人保存起来 * @param person */ public void attach(Person person) { System.out.println(person.getName() + "关注了天气预报"); persons.add(person); } /** * 通知所有的观察者 */ public void notifyAllObservers() { for (Person person : persons) { person.receive(); } } }
参考: