Java设计模式横向分为三种:创建型,结构性,行为型。纵向又可以分为两种:类模式与对象模式。

      wKiom1cGos2wy50JAAI5A3ChaTk533.jpg

现在介绍其中一种,观察者设计模式。

      所谓观察者通俗来说就是:很多Observer类观察一个Observable类。(很多观察者观察一个东西),最典型的例子就是全球投资者观察股市波动时侯,只要股价发生变化,那么投资者一定是同时观察到股价变化。并接受这条信息。

      那么股价作为被观察的对象的属性,一定是在被观察者对象中产生,改变的方法也在被观察者中产生,通过股价改变,从而使得所有观察者接受到信号,而这个信号触发所导致的结果的方法一定在观察者中产生。

      wKiom1cGpc7CnPeKAADeiYOs2zg489.jpg


      在jdk中java.util.* 已经提供了Observable和Observer去实现观察者模式。下面通过代码来理解。

      
产生随机价格的工具类:

package myjava.jdk;
import java.util.Random;
public class RandomUtil {
    public static float[] getRandomFloatArray(int randomCnt) {
        Random r = new Random();
        float[] sort = new float[randomCnt];
        for (int i = 0; i < randomCnt; i++) {
            sort[i] = r.nextFloat();
        }
        return sort;
    }
}

  观察者模式:

package myjava.jdk;
import java.util.* ;
class Stock extends Observable{    
    private float price ;// 股价
    public Stock(float price){
        this.price = price ;
    }
    public float getPrice(){
        return this.price ;
    }
    public void setPrice(float price){
        // 每一次修改的时候都应该引起观察者的注意
        super.setChanged() ;          // 设置变化点
        super.notifyObservers(price) ;// 价格被改变
        this.price = price ;
    }
    public String toString(){
        return "股价价格为:" + this.price ;
    }
}; 
class StockPriceObserver implements Observer{
    private String name ;
    public StockPriceObserver(String name){    // 设置每一个投资者的名字
        this.name = name ;
    }
    public void update(Observable o,Object arg){
        if(arg instanceof Float){
            System.out.print(this.name + "观察到股价更改为:") ;
            System.out.println(((Float)arg).floatValue()) ;
        }
    }
};
public class ObserStockChange{
    public static void main(String args[]) throws Exception{
        Stock h = new Stock(1000000) ;
        //输出顺序与加入顺序相反
        StockPriceObserver hpo1 = new StockPriceObserver("高盛集团") ;
        StockPriceObserver hpo2 = new StockPriceObserver("Morgan Stanley") ;
        StockPriceObserver hpo3 = new StockPriceObserver("Warren Buffett") ;
        StockPriceObserver hpo4 = new StockPriceObserver("中信证券") ;
        h.addObserver(hpo1) ;
        h.addObserver(hpo2) ;
        h.addObserver(hpo3) ;
        h.addObserver(hpo4) ;
        System.out.println(h) ;
        //设置十个变化的价格,每隔3秒钟更新一次
        float[] sort = RandomUtil.getRandomFloatArray(10);
        for(int i=0; i<sort.length; i++){
            float price = sort[i];
            h.setPrice(price*1000);
            System.out.println(h) ;  
            System.out.println("第"+(i+1)+"次股价变化"+"--------------------");  
            Thread.sleep(3000);
        }
    }
};

       程序运行结果:

       wKioL1cGqzOTfrbOAALMfR0HGb4111.jpg

      

       在Tomcat整个启动时候,用到了观察者设计模式。在Lifecycle,Servlet实例创建,Session管理,Container管理大量用到此模式。因为容器状态改变后,tomcat里面组件也会相应的发生变化。可谓牵一发而动全身。

       wKiom1cGrJTBYoWXAACaIlobpug970.jpg

      还有request请求到达tomcat时候,就知道要访问那个子容器了,为什么?因为MappingListner保留了所有容器的信息,只要容器改变就会通知到它。这也是观察者模式的一个应用。