设计模式之观察者模式

来源:互联网 发布:mac jdk 默认安装路径 编辑:程序博客网 时间:2024/05/21 17:17

什么是观察者模式。举个列子,现实生活中有猎头这个职业,他们是专门给人介绍工作的。小明有一天失业了,于是找到了这个猎头,对猎头说我给你钱你那一有工作就通知我。同样的小红也是这样,给钱给猎头,让他一有工作就通知她。我们来看下这里猎头就是一个被观察者,而小明,小红就是观察者。当被观察者有一个消息就通知其下面的观察者。被观察者可以增加许多个观察者(猎头可以收很多人的钱,然后让他们作为自己的观察者)。被观察者也可以去掉观察者(小明找到工作了,于是就多猎头说我找到工作了,你以后有工作就不需要通知我了)。从这个情景我们可以看出观察者模式包含2类对象1,观察者2,被观察者他们直接的关系是一个被观察者下面可以有许多个观察者。观察者模式主要的运用就是当许多类依赖的那个类发生变动时这个变动的类能通知那些观察者,接下来我们就举个列子(这里我们自己写一个观察者模式):

package com.djk.design.observer;import java.util.ArrayList;import java.util.List;/** * 观察者模式 * @author djk * */public class ObserverTest{public static void main(String[] args){//生成一个被观察者Headhunting headhunting = new Headhunting();//生成一个观察者Observer observer1 = new XiaoHong();//添加一个观察者headhunting.registerObserver(observer1);//生成一个观察者Observer observer2 = new XiaoMing();//添加一个观察者headhunting.registerObserver(observer2);headhunting.setWork("java工程师");try {System.out.println("猎头给介绍工作后2个人去面试了");Thread.sleep(3000);} catch (Exception e){}//此时小明面试过了于是他对对猎头说下次有工作不要通知他了,猎头于是在通知对象的名单中把他去掉headhunting.removeObserver(observer2);//接受猎头又有份新的工作 此时会发现猎头只有通知了小红headhunting.setWork("java测试");}}/** * 被观察者接口 */interface ObserverAble{void registerObserver(Observer observer);void removeObserver(Observer observer);void notifyObserver(String...args);}/** * 观察者 * @author djk * */interface Observer{void update(String...args);}/** * 猎头作为被观察者 * @author djk * */class Headhunting implements ObserverAble{//存放观察者的容器private List<Observer> list =null;private String work;public Headhunting (){list  = new ArrayList<Observer>();}/** * 通知观察者 */public void notifyObserver(String... args) {//没有观察者if(list.size() ==MyConstant.NODATE.getValue()){System.out.println("哎,这年头钱难赚啊,没有人要介绍工作我要下岗了。。。。");return ;}for(Observer observer: list){observer.update(args);}}/** * 增加观察者 */public void registerObserver(Observer observer) {list.add(observer);}/** * 删除观察者 */public void removeObserver(Observer observer){int index = list.indexOf(observer);if(index >=0){list.remove(index);}}public String getWork() {return work;}public void setWork(String work){this.work = work;notifyObserver(work);}}/** * 小明观察者 * @author djk * */class XiaoMing implements Observer{public void update(String... args) {System.out.println("我是小明,发现猎头有新工作:"+args[0]);}}/** * 小红观察者 * @author djk * */class XiaoHong implements Observer{public void update(String... args){System.out.println("我是小红,发现猎头有新工作:"+args[0]);}}/** * 常量类 * @author djk * */enum MyConstant{NODATE(0);private int value;private MyConstant(int value){this.value  = value;}public int getValue() {return value;}public void setValue(int value) {this.value = value;}}


java 的djk其实已经提供了对观察者模式的支持。被观察者只要继承Observable基类,观察者只要实现Observer接口,把上面的代码用jdk提供的观察者模式来实现:

package com.djk.design.observer;import java.util.Observable;import java.util.Observer;/** * 使用jdk提供的观察者模式 * @author djk * */public class ObserverTest2{public static void main(String[] args) {//被观察者Headhunting1 headhunting1 = new Headhunting1();//观察者小红Observer xiaohong = new XiaoHong1();//添加观察者headhunting1.addObserver(xiaohong);//观察者小明Observer xiaoming = new XiaoMing1();//添加观察者headhunting1.addObserver(xiaoming);headhunting1.setWork("java工程师");try {System.out.println("猎头给介绍工作后2个人去面试了");Thread.sleep(3000);} catch (Exception e){}//此时小明面试过了于是他对对猎头说下次有工作不要通知他了,猎头于是在通知对象的名单中把他去掉headhunting1.deleteObserver(xiaoming);//接受猎头又有份新的工作 此时会发现猎头只有通知了小红headhunting1.setWork("java测试");}}/** * 猎头(被观察者) * @author djk * */class Headhunting1 extends Observable{private String work;public String getWork() {return work;}public void setWork(String work) {this.work = work;setChanged();notifyObservers(work);}}/** * 观察者小红 * @author djk * */class XiaoHong1 implements Observer{public void update(Observable o, Object arg){System.out.println("我是小红,猎头有新工作了:"+arg);}}/** * 观察者小明 * @author djk * */class XiaoMing1 implements Observer{public void update(Observable o, Object arg){System.out.println("我是小明,猎头有新工作了:"+arg);}}


这里要注意的是,使用jdk的观察者模式要通知观察者时首先要调用  setChanged();来通知一下有新的消息了,如果没有设置即使有新的消息也不会通知观察者.

原创粉丝点击