观察者模式-Observer(Java实现)
观察者模式-Observer
当一个对象变化时,其它依赖该对象的对象都会收到通知, 并且会随着变化!对象之间是一种一对多的关系。
换一种表达方式: 有很多观察者们依赖于(观察)同一个对象(主题), 当这个被依赖的对象(主题)变化时, 观察者们也会随之变化.
本文中的例子如下: 有一个进度生成器, 用来模拟进度条的数值. 当进度数值更新后, 就会通知进度栏更新值. 也就是进度栏是观察者, 随时间在变的进度值是主题内容.
Observer接口
这是观察者的统一定义. 主题被修改时, 通过调用update()方法来通知观察者更新.
/** * 观察者接口-观察者的统一定义 */ public interface Observer { /** * Observer(观察者)会被数值生成器通知, 来更新自己的状态 */ void update(ProgressBar generator); }
DigitObserver类
数字进度类. 这是其中一种观察者的实现, 也是一种具体的进度条.
/** * 将进度以数字形式展现出来 */ public class DigitObserver implements Observer { /** * Observer(观察者)会被数值生成器通知, 来更新自己的状态 */ @Override public void update(ProgressBar generator) { System.out.println("数字版进度条:" + generator.getNumber() + "%"); } }
GraphObserver类
图形进度条, 这是其中一种观察者的实现, 也就是一种具体的进度条.
/** * 将进度条以进度栏形式展现出来 */ public class GraphObserver implements Observer { /** * Observer(观察者)会被数值生成器通知, 来更新自己的状态 */ @Override public void update(ProgressBar generator) { System.out.print("图形版进度条:"); int count = generator.getNumber(); for (int i = 0; i < count; i++) { System.out.print("*"); } System.out.println(""); } }
ProgressBar类
由本类来模拟 随时间在涨的进度数值, 进度值变更后, 会通知进度条来更新自己的值.
/** * 生成数值的类, 同时会保存观察者们, 当数值生成的时候就会去通知所有观察者们 */ public class ProgressBar { /** * 保存Observer们 */ private ArrayList<Observer> observers = new ArrayList<>(); /** * 当前数值 */ private int number; public int getNumber() { return number; } /** * 生成数值, 并通知给观察者们 */ public void execute() { for (int i = 0; i <= 100; i += 10) { number = i; notifyObservers(); } } /** * 注册Observer */ public void addObserver(Observer observer) { observers.add(observer); } /** * 向Observer发送通知 */ public void notifyObservers() { for (Observer o : observers) { o.update(this); } try { System.out.println(); Thread.sleep(400); } catch (InterruptedException e) { e.printStackTrace(); } } }
Main
public class Main { public static void main(String[] args) { // 进度值 ProgressBar progressBar = new ProgressBar(); // 图形进度条, 和数值进度条 都订阅了这个进度值 // 在进度值变化时, 这两个观察者就会更新自己的进度 progressBar.addObserver(new DigitObserver()); progressBar.addObserver(new GraphObserver()); // 进度值开始变动 progressBar.execute(); } }
运行结果如下:
---------------------------------------------------------
学如不及,犹恐失之
学如不及,犹恐失之