观察者模式

这是我第一次写那么具体的博客,出错了勿笑,还请指出。

观察者模式

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新。观察者模式中的被观察者就是一,多个依赖者就是观察者。如下图:

 

 

 

就象我们很小的时候一家人其乐融融,聊着家常的时候,会有一个人逗你,你会根据他的行为做出各种反应。你的家人会根据你的反应做出各种反应。这就是观察者模式的一种体现,其中,逗你的人是被观察者(被你观察),你是观察者;根据你的反应做出各种行为的家人是观察者(观察你),你又是被观察者。所以,观察者也可以是被观察者。

 

 

利用观察者模式,被观察者/可观察者是具有状态的对象,并且可以控制这些状态。也就是说,有“一个”具有状态的对象。另一方面,观察者使用这些状态,虽然这些状态并不属于他们,有许多的观察者,依赖被观察者/可观察者来告诉他们状态何时改变了。这就产生一个关系:“一个”被观察者/可观察者对“多个”观察者的关系。因为被观察者/可观察者是真正拥有数据的对象,观察者是被观察者/可观察者的依赖者,在数据变化更新时,这样比起让许多对象控制同一份数据来,可以得到更干净的OO设计。

 

观察者模式类图:

 

当两个对象之间松耦合,它们依然可以交互,但是不太清除彼此的细节。

 

观察者模式提供了这一种对象设计,让被观察者/可观察者和观察者之间松耦合。

 

看到上面的图,你就会明白了吧。

关于观察者的一切,被观察者/可观察者只知道观察者实现了某个接口(也就是Observer)。主题不需要知道观察者的具体类是谁、做了些什么或者其他任何细节。

 

任何时候我们都可以增加新的观察者。因为被观察者/可观察者唯一依赖的东西是一个实现Observer接口的对象列表,所以我们可以随时增加新观察者。事实上,在运行时我们可以用新的观察者取代现有的观察者,被观察者/可观察者不会受到任何影响。同样的也可以在任何时候删除某些观察者。

 

在新类型的观察者出现时,被观察者/可观察者的代码不需要修改。假如我们有个新的具体类需要当观察者,我们不需要为了兼容新类型而修改被观察者/可观察者的代码,所有要做的就是在新的类里实现此观察者接口,然后注册通过方法regiserObserver()为观察者即可。观察者/可观察者不在乎别的,它只会通过方法notifyObserver()发生通知给所有实现了观察者接口的对象。

 

我们可以独立地复用被观察者/可观察者或者观察者,如果我们在其他地方需要使用被观察者或者观察者,可以轻易地复用,因为二者并非紧耦合。

 

当然,在被观察者/可观察者的状态更新时,被观察者/可观察者可以通过推的方法(直接向观察者实现的update()方法中传递数据)向观察者中传递数据,也可以通过拉的方式(被观察者/可观察者通过观察者实现的update()方法通知观察者我的数据改变了,观察者根据自己的需要通过被观察者/可观察者的getState()方法获取自己需要的数据)方式传递数据给观察者。这两种方法在具体的情况下各有利弊,需要根据具体要求选择。

 

下面通过具体例子来解释下:

在一家人其乐融融的聊天时,大家突然注意到在旁边玩耍的幼小的你,这时候你就是被观察者/可观察者,你的家人就是观察者。

 

//被观察者/可观察者接口

interface Observabel{

         void registerObserver(Observer observer);

         void removeObserver(Observer observer);

         void notifyObserver();

}

 

//观察者接口

interface Observer{

         //当被观察者/可观察者状态改变时调用

         void update(String str);

}

//被观察者/可观察者具体实现(一个child)

class Child implements Observable{

  private ArrayList<Observer> mObservers;

  public Child(){

            //初始化观察者队列,用于管理观察者

       mObservers = new ArrayList<Observer>();

  }

  //注册观察者方法

     @Override

     public void registerObserver(Observer observer){

       mObserver.add(observer);

  }

 

  //撤销观察者方法

  @Override

  public void removeObserver(Observer observer){
        int index = mObserver.indexOf(observer);

            if(index > 0){

              mObserver.remove(observer);

           }

  }

 

     //通知观察者,被观察者/可观察者状态改变的方法

     //并且使用推的方式,直接将状态数据传递给观察者update()方法

  @Override

  public void notifyObserver(String str){

        for(int i = 0; i < mObservers.getSize();  i ++){

             Observer o = (Observer)mObservers.get(i);

             o.update(str);

    }

     }

}

 

//一个观察者(孩子的父亲)

class ChildFather implements Observer{

   private Observable mObservable;

       //在构造方法中注册观察者

       public ChildFather(){

         mObservable = new Child();

         mObservable.rigesterObserver(this);

  }

 

  //被观察/可观察者状态更新时,观察者根据这个方法做出具体的响应

     @Override

     public void update(String str){

       if(str.equal(“拍手并且张嘴呵呵的笑”)){

            System.out.println(“呵呵”);

    }else if(str.equal(“摇摇晃晃的向前走”)){
               System.out.println(“呵呵”);

    }else if(str.equal(“牙牙学语,嘴里喊着“妈妈,妈妈···””)){
                  System.out.println(“快喊一声爸爸来听听”);

    }

  }

}

 

//一个观察者(孩子的妈妈)

class ChildMother implements Observer{

   private Observable mObservable;

       //在构造方法中注册观察者

       public ChildMother (){

         mObservable = new Child();

         mObservable.rigesterObserver(this);

  }  

  //被观察/可观察者状态更新时,观察者根据这个方法做出具体的响应

     @Override

     public void update(String str){

       if(str.equal(“拍手并且张嘴呵呵的笑”)){

         System.out.println(“看你高兴的”);

    }else if(str.equal(“摇摇晃晃的向前走”)){
            System.out.println(“慢着,别摔着了”);

    }else if(str.equal(“牙牙学语,嘴里喊着“妈妈,妈妈···””)){
            System.out.println(“真乖”);

    }

  }

}

 

//一个观察者(其他人)

class ChildOther implements Observer{

  private Observable mObservable; 

      //在构造方法中注册观察者

      public ChildMother (){

        mObservable = new Child();

        mObservable.rigesterObserver(this);

  }

 

  //被观察/可观察者状态更新时,观察者根据这个方法做出具体的响应

     @Override

     public void update(String str){

       if(str.equal(“拍手并且张嘴呵呵的笑”)){

         System.out.println(“你看他,一点儿也不认生”);

    }else if(str.equal(“摇摇晃晃的向前走”)){
                System.out.println(“真聪明,都学会走步了”);

    }else if(str.equal(“牙牙学语,嘴里喊着“妈妈,妈妈···””)){
                System.out.println(“会喊妈妈了,呵呵”);

    }

  }

}

 

public class Main{

  public static void main(string[] arg){

        //被观察者/可观察者对象

           Child child = new Child();

           //观察者对象(父亲)

           Observer father = new ChildFather();

           //观察者对象(母亲)

    Observer mother = new ChildMother();

    //观察者对象(其他人)

           Observer other = new ChildOther();

           //被观察者/可观察者状态改变,并通知所有的观察者它的状态改变了

          child.notifyObsever(“拍手并且张嘴呵呵的笑”);

          child.notifyObserver(“摇摇晃晃的向前走”);

          child.notifyObserver(“牙牙学语,嘴里喊着“妈妈,妈妈···””);    

  }

}

 

posted @ 2016-05-23 11:46  xavier9648  阅读(222)  评论(0编辑  收藏  举报