观察者模式-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();
    }
}

  

 运行结果如下: 

 

posted @ 2018-05-21 22:41  GoldArowana  阅读(1049)  评论(0编辑  收藏  举报