观察者模式

来源:互联网 发布:linux查看文件的命令 编辑:程序博客网 时间:2024/04/29 02:39

实现观察者模式通用步骤

  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. 拉模型(目标对象在通知观察者对象的时候,值传递少量的信息,如果观察者需要更具体的信息,由观察者主动到目标对象中获取,相当于是观察者从目标对象中拉数据)
0 0