java设计模式-观察者模式

今天就来说下我了解的观察者模式。

观察者模式(发布-订阅模式)中存在两种对象,一个是被观察的,即目标(subject),另一个就是观察者(observe)。一个目标可以对应一个观察者:一对多的关系;或者一个目标对应多个观察者,是一对多的关系;也可以出现多个目标对应一个观察者。
观察者模式分为两种:推模式和拉模式。推模式就是目标就观察者需要的那部分数据推送给观察者;而拉模式是目标不知道观察者需要哪部分数据,直接将自己的引用给了观察者。
无论是哪一种模式都需要四个部分组成:目标超类、观察者接口、具体目标类、具体观察者类。下面我们先看看推模式的实现:

Subject

public class Subject {
    //注册对应观察者用的List
    private ArrayList<Observe> observes = new ArrayList<Observe>();
    /**
     * 向注册用List里添加observe
     * @param observe
     */
    public void attachObserve(Observe observe){
        observes.add(observe);
    }
    /**
     * 从注册用List中删除指定的observe
     * @param observe
     */
    public void detach(Observe observe){
        observes.remove(observe);
    }
    protected void notifyObserves(){
        for(Observe observe:observes){
            observe.update(((ConcreteSubject)this).getState());
        }
    }
}

Observe

public interface Observe {
    public void update(String state);
}

ConcreteSubject

public class ConcreteSubject extends Subject{
    //目标状态标记
    private String state;
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
        this.notifyObserves();
    }
}

ConcreteObserve

public class ConcreteObserve implements Observe{
    //观察者状态标记
    private String observeState;
    @Override
    public void update(String state) {
        observeState = state;
        System.out.println("观察者状态已更新为"+observeState);
    }
}

观察者模式(推模式)测试代码

public class ObservePatternTest {
    public static void main(String[] args) {
        //1.实例化具体目标类
        ConcreteSubject subject = new ConcreteSubject();
        //2.实例化具体观察者类
        ConcreteObserve observe = new ConcreteObserve();
        //3.注册观察者
        subject.attachObserve(observe);
        //4.改变目标状态标记
        subject.setState("目标状态改变啦!");
        //5.控制台验证观察者状态标记
    }
}

拉模式我就不再用具体代码去描述了,简单来说就是将观察者的update方法的参数改为目标的引用就好了。其实拉模式就可以理解为把目标自身扔给了观察者,让观察者自己去取出那些对其有用的信息。这点也是推模式和拉模式的区别所在。

另外,在java源码当中也封装了自己的观察者模式,使用起来相对更简单些

java中的观察者模式是已经把抽象的目标封装为java.util下的Observable类,而观察者则封装为Observe接口。下面看看怎么使用Java的观察这模式。

ConcreteSubject

public class ConcreteSubject extends Observable {
    private String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
        //下面这句的调用在是用java的观察者模式时必不可少的
        this.setChanged();
        //使用推模型,
        this.notifyObservers(subjectState);

//      //使用拉模型
//      this.notifyObservers();
    }
}

ConcreteObserve

public class ConcreteObserve implements Observer{

    private String observeName;

    /**
     * 第一个参数是目标的对象,采用的是拉模型;第二参数是推模型。
     */
    @Override
    public void update(Observable o, Object arg) {
        //采用推的方式进行状态同步
        System.out.println(observeName+"收到了目标的推送:"+arg);

        //采用拉的方式进行状态同步
        System.out.println(observeName+"收到了消息,主动到目标对象里去寻找:"+((ConcreteSubject)o).getSubjectState());
    }

    public String getObserveName() {
        return observeName;
    }

    public void setObserveName(String observeName) {
        this.observeName = observeName;
    }
}

java中的观察者模式测试代码

public class ObservePatternTest {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();

        ConcreteObserve observe = new ConcreteObserve();
        observe.setObserveName("cythine");

        subject.addObserver(observe);

        subject.setSubjectState("明天天气不错!");
    }
}

对于观察者模式的使用,精髓就是大家所说的“触发联动”。好吧,就先写这么多,余下的以后再补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值