观察者模式又叫做发布-订阅(Publish/Subscribe)模式、源-监听(Source/Listener)模式。它定义了一种一对多的依赖关系,一个主题,多个观察者,当主题发生变化的时候,会主动的通知观察者,这样观察者便能针对主题发生的变化,执行某些对应的动作。

    实现该模式通常需要两个过程:订阅者订阅、发布者发布

    1. /**
    2. * 主题,也是被观察者
    3. */
    4. public interface Observable {
    5. /**
    6. * 添加观察者
    7. */
    8. void addObsrver(Observer observer);
    9. /**
    10. * 删除观察者
    11. */
    12. void deletebserver(Observer observer);
    13. /**
    14. * 事件发生,通知观察者
    15. */
    16. void notifybservsers();
    17. }
    1. /**
    2. * 观察者
    3. */
    4. public interface Observer {
    5. /**
    6. *
    7. * @param observable
    8. * @param arg
    9. */
    10. void update(Observable observable, Object arg);
    11. }

    以Tomcat中Lifecycle为例,我们这里简单模仿一下,实现上面的两个接口。

    1. /**
    2. * 主题的具体实现
    3. */
    4. public class Container implements Observable {
    5. /**
    6. * 观察者列表
    7. */
    8. private List<Observer> observers = new ArrayList<>();
    9. /**
    10. * 添加观察者
    11. */
    12. void addObsrver(Observer observer) {
    13. observers.add(observer);
    14. }
    15. /**
    16. * 删除观察者
    17. */
    18. void deletebserver(Observer observer) {
    19. observers.remove(observer);
    20. }
    21. /**
    22. * 事件发生,通知观察者
    23. */
    24. void notifybservsers() {
    25. for (Observer observer : observers) {
    26. observer.update(this, "container start");
    27. }
    28. }
    29. }
    1. /**
    2. * 观察者的具体实现
    3. */
    4. public class ContainerConfig implements Observer {
    5. /**
    6. *
    7. * @param observable
    8. * @param arg
    9. */
    10. void update(Observable observable, Object arg) {
    11. String event = (String) arg;
    12. if (event.equals("container start")){
    13. // do container configs
    14. }
    15. }
    16. }

    实际上,监听器模式也是如此,观察者相当于事件的监听者,被观察者相当于事件和事件源,事件源经过事件的封装传给监听器,当事件源触发事件后,监听器接收到事件对象可以回调事件的方法。