Java设计模式之观察者模式

来源:互联网 发布:金山词霸mac 屏幕取词 编辑:程序博客网 时间:2024/06/03 20:43

观察者模式的简单介绍

观察者模式的基本定义:

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所以依赖于它的对象都得到通知并且被自动更新,然后在接收到通知以后各个对象做出相应的动作,这里涉及到两个概念(观察者和被观察者(目标类)),被观察者只能有一个,而观察这个观察者的对象可以用多个(一对多)

我们再清楚的认识一下观察者模式:

1.目标与观察者之间的关系:一对一,一对多,多对一等2.单向依赖:观察者依赖目标,而不是目标依赖观察者,观察者是被动的,目标是主动的3.触发通知的时机:目标对象的状态发生维护之后触发(比如:先赋值内容再通知是对的,而反过来就会出现问题)

观察者模式的命名建议:

1.目标接口的定义,建议在名称后面跟Subject2.观察者接口的定义,建议在名称后面跟Observer3.观察者接口的更新方法,建议名称为update,参数的个数及类型不受限制

观察者模式实现的两种方式(推模型和拉模型):

推模型:目标对象主动向观察者推送目标的详细信息,推送的信息通常是目标信息的全部或部分信息

拉模型:目标对象在通知观察者的时候,只传递少量信息,如果观察者需要更具体的信息,由观察者主动到目标对象中获取,相当于是观察者从目标对象中拉数据,一般这种模型的实现中,会把目标对象自身通过update方法传递给观察者

public void update(Subject subject);//拉模型
//从拉模型到推模型的修改如下:public void update(String content);//指定推送的内容contentprotected void notifyObservers(String content){//通知所有注册的观察者对象    for(Observer observer:observers){        observer.update(content);    }}

推模型和拉模型两种模型的比较:

推模型是假定目标对象知道观察着需要的数据,推模型会使观察者对象难于复用

拉模型是目标对象不知道观察着具体需要什么数据,因此把自身传给观察者,由观察者来取值,拉模型下,update方法的参数是目标对象本身,基本上可以适应于各种情况的需要

使用观察者模式的场景—–触发联动(本质):

1.当一个抽象模型有两个方面,其中一个方面的操作依赖于另一个方面的状态变化

2.如果更改一个对象的时候,需要同时连带改变其他的对象,而且不知道究竟应该有多少对象需要被连带改变

3.当一个对象必须通知其他的对象,但是你又希望这个对象和其他被通知的对象是松散耦合的

观察者模式的通用代码和简单例子

来看看观察者模式的通用代码:

观察者模式通用代码的实现步骤:

1.目标对象的定义2.具体的目标对象的定义3.观察者接口的定义

目标对象类(Subject.java):

/*目标对象,它知道观察它的观察者,并提供注册(添加)和删除观察者的接口*/public class Subject {    private List<Observer> observers=new ArrayList<Observer>();//保存注册的观察者对象    public void attach(Observer observer){//将观察者添加到观察者集合中去        observers.add(observer);    }    public void detach(Observer observer){//删除集合中的观察者对象        observers.remove(observer);    }    protected void notifyObservers(){//通知所有注册的观察者对象        for(Observer observer:observers){            observer.update(this);        }    }}

具体的目标对象(ConcreteSubject.java):

/*具体的目标对象,负责把有关状态存入到相应的观察者对象中*/public class ConcreteSubject extends Subject {    private String sbujectState;//目标对象的状态    public String getSbujectState() {        return sbujectState;    }    public void setSbujectState(String sbujectState) {        this.sbujectState = sbujectState;        this.notifyObservers();//状态发生改变时通知观察者    }}

观察者接口(Observer.java):

/*定义一个观察者接口,定义一个更新的接口给那些在目标发生改变的时候被通知的对象*/public interface Observer {    public void update(Subject subject);//subject是传入的目标对象,方便获取相应的目标对象的状态}

具体的观察者对象(ConcreteObserver.java):

/*具体的观察者对象,实现了更新的方法,使自身的状态和目标的状态保持一致*/public class ConcreteObserver implements Observer{    private String observerState;//观察者的状态    @Override    public void update(Subject subject) {//获取目标类的状态同步到观察者状态中去        observerState=((ConcreteSubject)subject).getSbujectState();    }}

观察者模式简单例子实现:使用观察者模式通用代码实现观察者模式的简单场景例子:http://paste.ubuntu.com/24252306/

利用Java提供的观察者模式实现

使用Java自带类实现观察者模式的简单例子:http://paste.ubuntu.com/24252765/

Java实现VS自己实现的对比四点:

1.不需要再定义观察者和目标接口(JDK已经定义)

2.具体的目标实现里面不需要再维护观察者的注册信息,Java中的java.util包下的Observable类里面已经实现

3.触发通知的方式有一点变化,要先调用setChanged方法,这个是Java为了帮助实现更精确的触发控制而提供的功能

4.具体观察者的实现里面,update方法其实能同时支持推模型和拉模型,这个Java在定义的时候,已经考虑

场景问题之区别对待观察者

实现下面功能的具体的代码示例:http://paste.ubuntu.com/24253024/

情况之一:如果天气是晴天,按照小明的女朋友需要下雨的条件,小明的老妈需要下雨或下雪的条件,则她们俩就都不需要通知了

情况之二:如果天气是下雨,则小明的女朋友需要通知,而小明的老妈也需要通知

情况之三:如果天气是下雪,则只需要通知小明的老妈

0 0
原创粉丝点击