观察者模式(View Pattern):对象之间多对一依赖的一种解决方案,被依赖的对象称之为Subject,依赖的对象称之为Observer,Subject通知Observer变化。
观察者模式就相当于咱们现实生活中的订牛奶业务以及订报纸业务等,用户就是那个Observer,牛奶公司或者报纸公司就是那个Subject,属于多对一的依赖关系。
Subject提供登记注册、移除、通知的方法
Observer负责接收输入
为了方便理解,这里就用订牛奶的业务来演示观察者模式的原理
1、Subject接口
public interface Subject { void addObserver(Observer observer); //登记 void deleteObserver(Observer observer); //删除 void notifyObservers(); //通知(拉取的方式,只通知Observer有更新,具体数据由Observer自己拉取) void notifyObservers(Object object); //通知(推送的方式,将具体数据推送给用户) }
2、Observer接口
public interface Observer { void update(Object object); }
3、Subject实现类(牛奶公司)
public class MilkEnterprise implements Subject { private Milk milk; private Set<Observer> set = new HashSet<>(); @Override public void addObserver(Observer observer) { if(!set.contains(observer)) set.add(observer); } @Override public void deleteObserver(Observer observer) { if(set.contains(observer)) set.remove(observer); } @Override public void notifyObservers() { for (Observer observer : set) { observer.update(null); } } @Override public void notifyObservers(Object object) { Milk milk = (Milk) object; for (Observer observer : set) { observer.update(milk); } } //设置更新数据 public void setData(Object object) { this.milk = (Milk) object; notifyObservers(this.milk); } }
4、Observer实现类(用户)
public class User1 implements Observer { @Override public void update(Object object) { System.out.println("-----user1获取到更新----------"); Milk milk = (Milk) object; //获取牛奶公司推送来的消息(这里只做简单的展示) System.out.println("最新牛奶品种:" +milk.getType()); System.out.println("最新牛奶价格:" +milk.getPrice()); } }
public class User2 implements Observer { @Override public void update(Object object) { System.out.println("-----user2获取到更新----------"); Milk milk = (Milk) object; //获取牛奶公司推送来的消息(这里只做简单的展示) System.out.println("最新牛奶品种:" +milk.getType()); System.out.println("最新牛奶价格:" +milk.getPrice()); } }
5、数据实体类(牛奶)
public class Milk { private String type; //牛奶品种 private float price; //牛奶价格 public String getType() { return type; } public void setType(String type) { this.type = type; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public Milk(String type, float price) { this.type = type; this.price = price; } }
6、测试类
public class MainTest { public static void main(String[] args){ MilkEnterprise enterprise = new MilkEnterprise(); enterprise.addObserver(new User1()); //登记用户1到牛奶公司 enterprise.addObserver(new User2());//登记用户2到牛奶公司 enterprise.setData(new Milk("酸奶",66.0f)); //牛奶公司有新牛奶出品 } }
输出结果:
-----user2获取到更新----------
最新牛奶品种:酸奶
最新牛奶价格:66.0
-----user1获取到更新----------
最新牛奶品种:酸奶
最新牛奶价格:66.0
由此结果我们可以看出观察者模式中,添加的顺序和最终通知的顺序是先进后出即类似栈的方式。
java中也有自己内置的观察者模式,Observable(class类,即被依赖者Subject),Observer(接口,即依赖者Observer),可是该内置的观察者模式有缺陷,即Observable不是接口而是class类,这就有java单继承的限制,所以具体使用时需具体分析场景灵活使用。