观察者模式(observer pattern)

观察者模式在软件编程中用的较多,我不善于表达我就用在网上看到的故事,和生活的例子说下基本思想 

故事:

   小雪是一个非常漂亮的女孩,漂亮的女孩总是有很多的追求者,而且追求者的队伍在不断的变动,随时有人进入这个队伍,也有人退出。男孩们追求女孩时总是表现出120%的关心,当小雪私自游玩时总是不断收到追求者询问小雪位置变动的消息,小雪也不胜其烦,但小雪是如此的一个善良的女孩,她总是打断自己正常的生活回复男孩们的消息。而男孩们由于要不断的关心小雪的位置变化也弄的精疲力竭,而且还影响正常的工作。在这样一个简单的故事场景中我们发现了什么?来看看小雪和男孩们的烦恼:
  1.男孩们必须不断的询问小雪的位置变化,从而打断正常的工作; 
  2.小雪也要不断的接受男孩们的询问,有的时候小雪的位置并没有发生变化,还是要不断的回复男孩们的询问,也影响正常的工作。

  3.如果给各个男孩们回复问题的方式都不尽相同,小雪还要知道不同的回复方式,而且不断的有新的男孩们增加进来,还不知道未来有什么新的回复方式。

    看到这么多烦恼,我们创意无限的Nokia公司给小雪和男孩们提出了解决方案:
    Nokia公司荣誉出品了一款带有GPRS功能的手机,该手机保存着一个订阅位置变化短信通知的电话列表,当该手机检测到位置发生变化就会向这个订阅列表里的所有手机发送短信。看到Nokia这个解决方案,男孩们和小雪都应该松一口气,他们各自都可以按照自己正常的生活习惯,只有状态发生变化时候各自才会进行通信

 

   观察者模式还可以用生活中一个例子来表达,就是从邮局订杂志。假如有一个叫 妮妮 的女孩在A邮局订了《时尚女孩》的杂志,又在B邮局订了《知音》杂志,并且告诉这两家邮局,如果杂志到了就给我打电话我自己来拿,然后邮局就在系统中注册下这个女孩姓名,电话等信息。妮妮剩下的就是等邮局的电话来取杂志了。如果杂志到了,邮局打电话给妮妮说,您的杂志到了,请到某某邮局来取(这相当于程序中把对象的引用——邮局名,传给观察者),如果只说您的杂志到了,请到邮局来取,妮妮怎么知道去哪个邮局拿杂志呀。

 

下面的程序模仿上面的情形,一个随机数产生对象和两个观察者,这两个观察者都在随机数产生对象那里注册了,意思说如果你产生了新的数字,就通知我一声。

 

 

 

 

 

1.Observer

 

package com.xinli.pattern.observer;

public interface Observer {   
    public abstract void update(NumberGenerator generator);   
} 

 2.NumberGenerator

package com.xinli.pattern.observer;

import java.util.ArrayList;   
import java.util.Iterator;   
  
/**  
 * @project JavaPattern  
 * @author sunnylocus     
 * @verson 1.0.0  
 * @date   Aug 27, 2008 1:35:34 PM  
 * @description 产生数值的抽象类  
 */  
public abstract class NumberGenerator {   
    private ArrayList observers = new ArrayList();  //存储Observer   
    /** 添加观察者*/  
    public void addObserver(Observer observer) {   
        observers.add(observer);   
    }   
    /** 删除观察者*/  
    public void delObserver(Observer observer) {   
        observers.remove(observer);   
    }   
    /** 通知所有观察者*/  
    public void notifyObservers() {   
        Iterator it = observers.iterator();   
        while(it.hasNext()) {   
            Observer o =(Observer) it.next();   
            o.update(this);//this相当于上面提到的邮局名   
        }   
    }   
    public abstract int getNumber();//获取数字   
    public abstract void generate();//产生数字   
}  

 

 3.RandomNumberGenerator

package com.xinli.pattern.observer;

import java.util.Random;   

/**  
 * @project JavaPattern  
 * @author sunnylocus     
 * @verson 1.0.0  
 * @date   Aug 27, 2008 1:48:03 PM  
 * @description 用于产生随机数及通知观察者的类  
 */  
public class RandomNumberGenerator extends NumberGenerator{   
    private Random random = new Random();//随机数产生器   
    private int number;   //用于存放数字   
  
    public void generate() {   
        for(int i=0 ; i < 5; i++) {   
            number = random.nextInt(10);//产生10数字以内的随机数   
            notifyObservers();  //有新产生的数字,通知所有注册的观察者   
        }   
    }   
    /** 获得数字*/  
    public int getNumber() {   
        return number;   
    }   
       
}  

 

4.NumberObserver

 

 

package com.xinli.pattern.observer;

public class NumberObserver implements Observer{   
    public void update(NumberGenerator generator) {   
        System.out.println("NumberObserver:"+ generator.getNumber());   
        try {   
            Thread.sleep(1000 * 3); //为了能清楚的看到输出,休眠3秒钟。   
        }catch(InterruptedException e) {   
            e.printStackTrace();   
        }   
    }  
}

 

 

 5.SymbolObserver

 

 

package com.xinli.pattern.observer;

/** 以符号表示观察者的类*/  
public class SymbolObserver implements Observer{   
    public void update(NumberGenerator generator) {   
        System.out.print("SymbolObserver:");   
        int count = generator.getNumber();   
           
        for(int i = 0 ; i < count; i ++) {   
            System.out.print("*^_^*  ");   
        }   
        System.out.println("");   
        try {   
            Thread.sleep(1000 * 3);   
        }catch(InterruptedException e){   
            e.printStackTrace();   
        }   
    }   
}

 

 

6.Main(测试类)

 

 

package com.xinli.pattern.observer;

public class Test {   
    public static void main(String[] args) {   
        //实例化数字产生对象   
        NumberGenerator generator = new RandomNumberGenerator();   
        //实例化观察者   
        Observer observer1 = new NumberObserver();   
        Observer observer2 = new SymbolObserver();   
        //注册观察者   
        generator.addObserver(observer1);   
        generator.addObserver(observer2);   
           
        generator.generate(); //产生数字   
    }   
}

 

 结果:

NumberObserver:9
SymbolObserver:*^_^*  *^_^*  *^_^*  *^_^*  *^_^*  *^_^*  *^_^*  *^_^*  *^_^* 
NumberObserver:1
SymbolObserver:*^_^* 
NumberObserver:9
SymbolObserver:*^_^*  *^_^*  *^_^*  *^_^*  *^_^*  *^_^*  *^_^*  *^_^*  *^_^* 
NumberObserver:6
SymbolObserver:*^_^*  *^_^*  *^_^*  *^_^*  *^_^*  *^_^* 
NumberObserver:3
SymbolObserver:*^_^*  *^_^*  *^_^* 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值