观察者模式(Observer)又称发布-订阅模式(Publish-Subscribe:Pub/Sub)。它是一种通知机制,让发送通知的一方(被观察方)和接收通知的一方(观察者)能彼此分离,互不影响。

观察者接口

public interface Observer {
    public abstract void update(NumberGenerator numberGenerator);
}

被观察的对象。主要包含变更时通知观察者的逻辑,这里使用的是循环同步通知。

public abstract class NumberGenerator {
    private List<Observer> observers = new ArrayList<>();

    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    public void deleteObserver(Observer observer) {
        observers.remove(observer);
    }

    //向观察者发送通知
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(this);
        }
    }

    public abstract int getNumber();

    public abstract void execute();
}

数字观察者,观察到改变就会输出数字

public class DigitObserver implements Observer {
    @Override
    public void update(NumberGenerator numberGenerator) {
        System.out.println(numberGenerator.getNumber());
        //为了看清楚结果,这里休眠一下
        try {
            Thread.sleep(100);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

图形观察者,观察到变化就会输出图形

public class GraphObserver implements Observer {
    @Override
    public void update(NumberGenerator numberGenerator) {
        int count = numberGenerator.getNumber();
        for (int i = 0; i < count; i++) {
            System.out.print("*");
        }
        System.out.println();
        //为了看清楚结果,这里休眠一下
        try {
            Thread.sleep(100);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

随机数生成

public class RandomNumberGenerator extends NumberGenerator {

    private int number;
    private Random random = new Random();

    @Override
    public int getNumber() {
        return number;
    }

    //生成数字,通知观察者
    @Override
    public void execute() {
        for (int i = 0; i < 20; i++) {
            number = random.nextInt(50);
            notifyObservers();
        }
    }
}

客户端调用

public class Main {
    public static void main(String[] args) {
        NumberGenerator numberGenerator = new RandomNumberGenerator();

        Observer observer1 = new DigitObserver();
        Observer observer2 = new GraphObserver();

        //添加观察者
        numberGenerator.addObserver(observer1);
        numberGenerator.addObserver(observer2);

        numberGenerator.execute();
    }
}

Java标准库有个java.util.Observable类和一个Observer接口,用来帮助我们实现观察者模式。但是,这个类非常不!好!用!实现观察者模式的时候,也不推荐借助这两个东东。