观察者模式

观察者模式简单来说就是,被观察者做了一件事,观察他的人都知道了他做了什么事,而且每个观察者对他做的这件事做出相应的反应。

假如:我是被观察者,我的所有亲戚朋友都是观察者,我的亲戚朋友都观察着我,那么如果我在打球,我的所有亲戚朋友都能知道我在打球,而且他们可能会对我在打球做出不同的反应。

 

定义就是:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。也叫做发布订阅模式。

具体看看代码实现,简单明了:

这是被观察者的抽象类

import java.util.Vector;

/**
 * 
 * 被观察者 抽象类
 * 
 * @author July
 * @create 2013-7-2 下午10:17:36
 *
 */
public abstract class Subject {
    
    // 定义一个观察者数组
    private Vector<Observer> obsVector = new Vector<Observer>();
    
    // 增加一个观察者
    public void addObserver(Observer o) {
        obsVector.add(o);
    }
    
    // 删除一个观察者
    public void delObserver(Observer o) {
        obsVector.remove(o);
    }
    
    // 通知所有观察者
    public void notifyObservers() {
        for (Observer o : obsVector) {
            o.update();
        }
    }
}

这是观察者接口

/**
 * 
 * 观察者
 * 
 * @author July
 * @create 2013-7-2 下午10:17:24
 *
 */
public interface Observer {
    // 更新方法
    public void update();
}

这是具体的被观察者,继承被观察者抽象类

/**
 * 
 * 具体被观察者,继承被观察者抽象类
 * 
 * @author July
 * @create 2013-7-2 下午10:18:21
 *
 */
public class ConcreteSubject extends Subject {
    public void doSomething() {
        System.out.println("被观察者开始做事!");
        /*
         * do something
         * 通知所有观察者
         */
        super.notifyObservers();
    }
}

这是具体的观察者1

/**
 * 
 * 具体观察者
 * 
 * @author July
 * @create 2013-7-2 下午10:21:21
 *
 */
public class ConcreteObserver implements Observer {
    @Override
    public void update() {
        System.out.println("接收到信息,并进行处理!");
    }
}

这是具体的观察者2

/**
 * 
 * 具体观察者
 * 
 * @author July
 * @create 2013-7-2 下午10:21:21
 *
 */
public class ConcreteObserver1 implements Observer {
    @Override
    public void update() {
        System.out.println("接收到信息,并进行处理--------------!");
    }
}

这是测试类,注意:观察者是可以动态添加删除的

public class Client {

    /**
     * 
     * 
     * @author July
     * @create 2013-7-2 下午10:15:08
     * 
     * @param args
     */
    public static void main(String[] args) {
        
        // 创建一个被观察者
        ConcreteSubject subject = new ConcreteSubject();
        
        // 定义一个观察者
        Observer obs = new ConcreteObserver();
        // 定义一个观察者
        Observer obs1 = new ConcreteObserver1();
        
        // 观察者观察被观察者
        subject.addObserver(obs);
        subject.addObserver(obs1);
        
        // 观察者开始活动了
        subject.doSomething();
        
    }

}

console输出:

被观察者开始做事!
接收到信息,并进行处理!
接收到信息,并进行处理--------------!

观察者模式的应用:

1、观察者和被观察者之间是抽象耦合,易于观察者和被观察者的扩展

2、简历一套触发机制,单一原则

观察者模式的使用场景:

1、关联行为场景。需要注意的是,关联行为是可拆分的,而不是“组合”关系。

2、事件多级触发场景

3、扩系统的消息交换场景,如消息队列的处理机制

观察者模式的注意事项:

1、广播链的问题:有无限级触发的时候,根据高手的经验,太多级触发不好控制,推荐做法是2级触发就好,比较好控制。

在JAVA种使用观察者模式,JAVA已经帮助我们做好了这种观察者模式,分别是JDK种的Observable(被观察者类)和Observer(观察者接口),实际使用中,创建被观察者接口(Inter),具体的被观察者继承Observable和实现Inter接口(自定义的接口),观察者只需要实现Observer接口即可。具体做法如下:

被观察者接口,我们自定义的

public interface Inter {
    public void haveBreakfast();
    public void haveFun();
}

具体的被观察者(韩非子),继承Observable类和实现Inter接口

public class HanFeiZi extends Observable implements Inter {

    @Override
    public void haveBreakfast() {
        System.out.println("韩非子:开始吃饭了。。。");
        // 通知所有观察者
        super.setChanged();
        super.notifyObservers("韩非子在吃饭");
    }

    @Override
    public void haveFun() {
        System.out.println("韩非子:开始娱乐了。。。");
        // 通知所有观察者
        super.setChanged();
        super.notifyObservers("韩非子在娱乐");
    }

}

具体的观察者,实现了Observer接口。。。

public class LiSi implements Observer {

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("李斯:观察到李斯活动,开始向老板汇报了。。,");
        reportToQinShiHuang(arg.toString());
        System.out.println("李斯:汇报完毕。。。
");
    }
    
    private void reportToQinShiHuang(String reportContet) {
        System.out.println("李斯:报告,秦老板!韩非子有活动了---->" + reportContet);
    }

}

测试类:

public class Client {

    /**
     * 
     * 
     * @author July
     * @create 2013-7-2 下午10:49:23
     * 
     * @param args
     */
    public static void main(String[] args) {
        HanFeiZi inter = new HanFeiZi();
        
        Observer lisi = new LiSi();
        
        inter.addObserver(lisi);
        
        inter.haveBreakfast();
        
    }

}

Console输出,无论有多少个观察者都是一样。

韩非子:开始吃饭了。。。
李斯:观察到李斯活动,开始向老板汇报了。。,
李斯:报告,秦老板!韩非子有活动了---->韩非子在吃饭
李斯:汇报完毕。。。

以上代码拷过去就能运行。。。。。。。。。。。。

OK!大功告成,这就是观察者模式,该模式在开发灰常常用。把该模式结合实际的项目,应用到里面去,会取得意想不到的效果。。。。。。。。

参考:《设计模式之禅》一书

原文地址:https://www.cnblogs.com/jinglingJuly/p/3168666.html