观察者模式 (Observer)的自我理解!欢迎指正

来源:互联网 发布:ubuntu安装wine软件 编辑:程序博客网 时间:2024/06/05 08:24

  这段时间由于学习Nodejs,其中的事件机制就是通过“观察者模式”实现的!所以顺带复习了一下

  学习一个新东西都避不开晦涩难懂的定义,每每看到那些定义都望而却步!接下来我们先看定义:

  观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对像在状态上发生变化时,

     会通知所有的观察者对象,让他们能够自动更新自己。(自动更新这一点只是表面的现象)

  

接下来用大白话翻译一下:  主题对象-----小明         观察者1-----小明的爸爸     观察者2---小明的妈妈

    这个故事的主角还是小明,小明从小顽皮不喜欢学习,最近决心改正,所以小明和爸爸妈妈说你们以后要监督我,所以每当小明的朋友叫

   小明出去玩的时候,小明都会特意跑去告诉爸爸妈妈,这时爸爸妈妈就知道小明要去玩了,随即爸爸妈妈把小明关在了房间里。


   下面我们从代码的角度去理解:

   在eclipse中创建一个项目,然后在建一个包,这里项目和包的名字自己定义。

  我的项目名称叫test,包名称叫com.observer.test

   观察者模式的组成:

  1、抽象主题角色

       把所有观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。

       抽象主题角色提供一些方法,可以增加和删除观察者角色,在这里要注意还需要一个通知观察者的功能(这就是所谓的自动)。

       抽象主题角色在具体代码中用一个接口来实现。


    代码部分:

    创建一个名称叫Watched的接口,用来实现抽象主题角色

   public interface Watched {


                    //增加一个观察者,比如小明让姐姐也监督他
                   public void addWatcher(Watcher watcher);


                   //删除观察者,后来爸妈管的太严了,就不让爸妈监督
                   public void removeWatcher(Watcher watcher);


                    //通知方法,要出去玩的时候主动去告诉爸妈
                   public void notifyWatchers(String str);
}


2、抽象观察者角色

  定义:为所有具体的观察者角色定义一个接口,在得到主题通知的时候更新自己。也是通过一个接口来实现抽象观察者角色。

  

  代码部分:

  创建一个名称为Watcher的接口,来实现抽象观察者角色

   

 public interface Watcher {
    

     //当爸妈知道小明要出去玩的时候,更新自己的态度
     public void update(String str);
  
}


3、具体主题角色

定义:在具体主题内部状态发生改变时,给所有登记过的观察者发出通知。具体主题角色用抽象主题角色的一个子类来实现。

这里具体主题角色名称为ConcreteWatched 

public class ConcreteWatched implements Watched {
  

//这个list用来保存观察者的引用,相当于小明自己要记住有哪些人监督他
 private List<Watcher> list = new ArrayList<Watcher>();


    //增加观察者的方法,相当于小明可以再找其他人监督他
@Override
public void addWatcher(Watcher watcher) {
       list.add(watcher);
}


 //删除观察者的方法,相当于小明爸妈太严,下次去玩就不告诉爸妈了
@Override
public void removeWatcher(Watcher watcher) {
       list.remove(watcher);
}

//通知观察者的方法,相当于小明要出去玩的时候告诉监督人
@Override
public void notifyWatchers(String str) {
       for(Watcher watcher:list){
      watcher.update(str);
       }


}

}


4、具体观察者角色

定义:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。

             如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。

            具体观察者角色用一个抽象观察者角色的子类来实现


具体观察者角色名称为ConcreteWatcher 

public class ConcreteWatcher implements Watcher {


     //更新具体观察者角色的状态,比如爸妈把小明关起来
@Override
public void update(String str) {
System.out.println(str);
}


}


5.测试类

最后一个测试类来测试写的代码,名称为Test 

public class Test {
   public static void main(String[] args) {
Watched xiaom=  new ConcreteWatched();//定义一个主题角色小明
Watcher  mother=new ConcreteWatcher();//定义一个观察者角色妈妈
Watcher  father=new ConcreteWatcher();//定义一个观察者角色爸爸
Watcher watcher3=new ConcreteWatcher();//定义一个观察者角色姐姐
 

        //增加观察者,相当于小明记住了监督人
xiaom.addWatcher(mother);
xiaom.addWatcher(father);
xiaom.addWatcher(sister);
 

xiaom.notifyWatchers("我要出去玩了");//主题对象通知观察者,相当于小明通知监督人
 
xiaom.removeWatcher(mother);//删除观察者,相当于小明下次不通知妈妈
 
xiaom.notifyWatchers("我要去打球");//因为删除了mother,所以这次接收通知的只有father和sister
  }
}


运行结果如下:

第一次通知了3个人,第二次通知了2个人

总结一下:观察者的状态是不会自动更新的,需要主题角色的通知。相当于小明要主动告诉监督人


0 0
原创粉丝点击