观察者模式

实现观察者模式通用步骤

  1. 目标对象的定义
  2. 具体的目标对象定义
  3. 观察者接口的定义
  4. 观察者接口的具体实现
/**目标对象.它知道观察它的观察者, 并提供注册和删除观察者的接口
 */
public class Subject {
    //用来保存注册的观察者对象
    private List<Observer> observers = new ArrayList<Observer>();
    public void attach(Observer observer) {
        observers.add(observer);
    }

    /*
    * 删除集合中的制定观察者
    * @param observer
    * */
    public void detach(Observer observer){
        observers.remove(observer);
    }

    /*
    通知所有注册的观察者对象
    * */
    protected void notifyObservers(){
        for(Observer observer: observers){
            observer.update(this);
        }
    }

}
public class ConcreteSubject extends  Subject {

    private  String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
        this.notifyObservers();
    }
}
/**这是一个观察者接口,定义一个更新的接口给那些在目标发生改变的时候通知的对象
 */
public interface Observer {
    /*
    * 更新接口
    * @param subject 传入目标对象,方便获取相应的目标对象的状态
    * */
    public void update(Subject subject);
}
/**具体的观察者对象,实现更新的方法, 使自身的状态和目标的状态保持一致
 */
public class ConcreteObserver implements  Observer {

    //观察者的状态
    private String observerState;
    @Override
    public void update(Subject subject) {
        observerState = ((ConcreteSubject)subject).getSubjectState();
    }
}

观察者案例(天气通知)

package com.test.WeatherObserverPattern;

import java.util.ArrayList;
import java.util.List;

/**目标对象.它知道观察它的观察者, 并提供注册和删除观察者的接口
 */
public class WeatherSubject {
    //用来保存注册的观察者对象
    private List<Observer> observers = new ArrayList<Observer>();

    //把订阅天气的人添加到订阅者列表中
    public void attach(Observer observer) {
        observers.add(observer);
    }

    /*
    * 删除集合中的制定订阅天气的人
    * @param observer
    * */

    public void detach(Observer observer){
        observers.remove(observer);
    }

    /*
    通知所有已经订阅天气的人
    * */
    protected void notifyObservers(){
        for(Observer observer: observers){
            observer.update(this);
        }
    }

}
package com.test.WeatherObserverPattern;


public class ConcreteWeatherSubject extends WeatherSubject {

    //获取天气的内容
    private  String weatherContent;

    public String getWeatherContent() {
        return weatherContent;
    }

    public void setWeatherContent(String weatherContent) {
        this.weatherContent = weatherContent;
        //内容有了, 说明天气更新了, 通知所有订阅的人
        this.notifyObservers();
    }
}
package com.test.WeatherObserverPattern;

/**具体的观察者对象,实现更新的方法, 使自身的状态和目标的状态保持一致
 * Created by yangshuangpeng on 17-1-25.
 */
public class ConcreteObserver implements  Observer {

    //观察者的名字,是谁收到了这个讯息
    private String observerName;

    //天气内容的情况,这个消息从目标出获取
    private String weatherContent;

    //提醒的内容
    private String remindThing;

    /*
        *获取目标类的状态同步至观察者的状态中
        * */

    @Override
    public void update(WeatherSubject subject) {
        weatherContent = ((ConcreteWeatherSubject)subject).getWeatherContent();
        System.out.println(observerName+"收到了"+ weatherContent + "," + remindThing);

    }

    public String getObserverName() {
        return observerName;
    }

    public void setObserverName(String observerName) {
        this.observerName = observerName;
    }

    public String getWeatherContent() {
        return weatherContent;
    }

    public void setWeatherContent(String weatherContent) {
        this.weatherContent = weatherContent;
    }

    public String getRemindThing() {
        return remindThing;
    }

    public void setRemindThing(String remindThing) {
        this.remindThing = remindThing;
    }
}
package com.test.WeatherObserverPattern;

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

测试类

package com.test.WeatherObserverPattern;

/**
 */
public class client {
    public static void  main(String[] args)
    {
        //1.创建目标
        ConcreteWeatherSubject weather =  new ConcreteWeatherSubject();

        //2.创建观察者
        ConcreteObserver      observer = new ConcreteObserver();
        observer.setObserverName("李明");
        observer.setRemindThing("适合出去玩");

        ConcreteObserver     observer1 =  new ConcreteObserver();
        observer1.setObserverName("李华");
        observer1.setRemindThing("适合散步");

        //3.注册观察者
        weather.attach(observer);
        weather.attach(observer1);

        //4.目标发布天气
        weather.setWeatherContent("明天天气晴朗, 蓝天白云");
    }
}

认识观察者模式

  1. 目标与观察者之间的关系
  2. 单向依赖
  3. 命名建议
  4. 触发通知时机
  5. 观察者模式的调用顺序图
  6. 通知的顺序

命名建议

目标接口的定义,建议在名称后面跟Subject
观察者接口的定义,建议在名称后面跟Observer
观察者接口更新的方法,建议名称为update

观察者模式实现的两种方式

  1. 推模型(目标对象主动向观察者推送目标的详细信息,通送的信息通常是目标对象的全部或部分数据)
  2. 拉模型(目标对象在通知观察者对象的时候,值传递少量的信息,如果观察者需要更具体的信息,由观察者主动到目标对象中获取,相当于是观察者从目标对象中拉数据)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值