Tomcat中设计模式-观察者模式

  1. 云栖社区>
  2. 博客列表>
  3. 正文

Tomcat中设计模式-观察者模式

晴天哥 2018-12-03 11:42:41 浏览382 评论0

摘要: 开篇  观察者模式的定义,有多个对象在关注着一个对象,如果这个对象的状态发生了改变,其它依赖(关注)它的对象就会收到通知,然后在接收到通知以后各个对象做出相应的动作。  观察者模式涉及到两个概念(观察者和被观察者),被观察者只能有一个,而观察这个观察者的对象可以用多个。

开篇

 观察者模式的定义,有多个对象在关注着一个对象,如果这个对象的状态发生了改变,其它依赖(关注)它的对象就会收到通知,然后在接收到通知以后各个对象做出相应的动作。

 观察者模式涉及到两个概念(观察者和被观察者),被观察者只能有一个,而观察这个观察者的对象可以用多个。【一对多】定义对象间的一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

观察者模式


观察者模式的demo

被观察者

  • 1.被观察者对象维护一个观察者的列表对象和注册观察者的接口。
  • 2.事件发生变化时候遍历所有观察者列表并触发事件。
  • 3.观察者统一实现某接口用以事件通知。
/***
 * 抽象被观察者接口
 * 声明了添加、删除、通知观察者方法
 *
 */
public interface Observerable {
    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObserver();
    
}


/**
 * 被观察者,也就是微信公众号服务
 * 实现了Observerable接口,对Observerable接口的三个方法进行了具体实现
 *
 */
public class WechatServer implements Observerable {
    
    //注意到这个List集合的泛型参数为Observer接口,设计原则:面向接口编程而不是面向实现编程
    private List<Observer> list;
    private String message;
    
    public WechatServer() {
        list = new ArrayList<Observer>();
    }
    
    @Override
    public void registerObserver(Observer o) {
        
        list.add(o);
    }
    
    @Override
    public void removeObserver(Observer o) {
        if(!list.isEmpty())
            list.remove(o);
    }

    //遍历
    @Override
    public void notifyObserver() {
        for(int i = 0; i < list.size(); i++) {
            Observer oserver = list.get(i);
            oserver.update(message);
        }
    }
    
    public void setInfomation(String s) {
        this.message = s;
        System.out.println("微信服务更新消息: " + s);
        //消息更新,通知所有观察者
        notifyObserver();
    }

}


观察者

  • 1.观察者需要定义统一的接口用以处理事件通知。
/***
 * 抽象观察者
 * 定义了一个update()方法,当被观察者调用notifyObservers()方法时,观察者的update()方法会被回调。
 *
 */
public interface Observer {
    public void update(String message);
}

/**
 * 观察者
 * 实现了update方法
 *
 */
public class User implements Observer {

    private String name;
    private String message;
    
    public User(String name) {
        this.name = name;
    }
    
    @Override
    public void update(String message) {
        this.message = message;
        read();
    }
    
    public void read() {
        System.out.println(name + " 收到推送消息: " + message);
    }
    
}


测试验证

package com.jstao.observer;

public class Test {
    
    public static void main(String[] args) {
        WechatServer server = new WechatServer();
        
        Observer userZhang = new User("ZhangSan");
        Observer userLi = new User("LiSi");
        Observer userWang = new User("WangWu");
        
        server.registerObserver(userZhang);
        server.registerObserver(userLi);
        server.registerObserver(userWang);
        server.setInfomation("PHP是世界上最好用的语言!");
        
        System.out.println("----------------------------------------------");
        server.removeObserver(userZhang);
        server.setInfomation("JAVA是世界上最好用的语言!");
        
    }
}

测试结果


Tomcat实现的观察者模式

观察者

  • 1.观察者实现统一的接口LifecycleListener,实现具体的方法lifecycleEvent。
  • 2.观察者的事件对象继承了EventObject类,这个有兴趣可以研究下。
  • 3.观察者的具体实现以HostConfig为例,实现了具体的lifecycleEvent方法。
public final class LifecycleEvent extends EventObject {
    private static final long serialVersionUID = 1L;

    public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
        super(lifecycle);
        this.type = type;
        this.data = data;
    }

    private final Object data;
    private final String type;

    public Object getData() {
        return data;
    }

    public Lifecycle getLifecycle() {
        return (Lifecycle) getSource();
    }

    public String getType() {
        return this.type;
    }
}


public interface LifecycleListener {
    public void lifecycleEvent(LifecycleEvent event);
}



public class HostConfig implements LifecycleListener {

    public void lifecycleEvent(LifecycleEvent event) {

        try {
            host = (Host) event.getLifecycle();
            if (host instanceof StandardHost) {
                setCopyXML(((StandardHost) host).isCopyXML());
                setDeployXML(((StandardHost) host).isDeployXML());
                setUnpackWARs(((StandardHost) host).isUnpackWARs());
                setContextClass(((StandardHost) host).getContextClass());
            }
        } catch (ClassCastException e) {
            log.error(sm.getString("hostConfig.cce", event.getLifecycle()), e);
            return;
        }

        if (event.getType().equals(Lifecycle.PERIODIC_EVENT)) {
            check();
        } else if (event.getType().equals(Lifecycle.BEFORE_START_EVENT)) {
            beforeStart();
        } else if (event.getType().equals(Lifecycle.START_EVENT)) {
            start();
        } else if (event.getType().equals(Lifecycle.STOP_EVENT)) {
            stop();
        }
    }
}

LifecycleListener.png

被观察者

  • 1.被观察者实现接口Lifecycle,实现addLifecycleListener和removeLifecycleListener方法。
  • 2.容器的基类LifecycleBase实现了被观察者功能,提供List lifecycleListeners保存被观察者。
  • 3.容器的具体实现当中都是继承LifecycleBase类,所以天然包含了被观察者的功能。
package org.apache.catalina;

public interface Lifecycle {
    public void addLifecycleListener(LifecycleListener listener);
    public LifecycleListener[] findLifecycleListeners();
    public void removeLifecycleListener(LifecycleListener listener);
}



public abstract class LifecycleBase implements Lifecycle {

    private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>();
    private volatile LifecycleState state = LifecycleState.NEW;

    public void addLifecycleListener(LifecycleListener listener) {
        lifecycleListeners.add(listener);
    }

    public LifecycleListener[] findLifecycleListeners() {
        return lifecycleListeners.toArray(new LifecycleListener[0]);
    }

    public void removeLifecycleListener(LifecycleListener listener) {
        lifecycleListeners.remove(listener);
    }

    protected void fireLifecycleEvent(String type, Object data) {
        LifecycleEvent event = new LifecycleEvent(this, type, data);
        for (LifecycleListener listener : lifecycleListeners) {
            listener.lifecycleEvent(event);
        }
    }
}

LifecycleBase容器


参考文章

【云栖快讯】阿里云栖开发者沙龙(Java技术专场)火热来袭!快来报名参与吧!  详情请点击

网友评论