码农成长计-观察者模式详解(java语言实现)

原创 2015年11月19日 10:24:13

本来自己这篇文章写在博客园上http://www.cnblogs.com/wujiandong,现在想到csdn上写写吐舌头

第一次写博客,请多多支持额!

一:什么是观察者模式:

      官方定义:定义对象间一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。    

      举个例子,很多人都会订阅天气预报,当气象台获得明天的天气情况(目标对象)时,就会短信通知订阅了天气预报的人(观察者),然后订阅者就会根据明天天气情况做出相应的处理(呆在家?出去踏青?出去购物...)

 

二:观察者模式的两个角色:

      第一个角色:目标对象(subject),被观察者关注的对象,它的改变引起观察者的改变,例如上面提到的天气情况。

      第二个角色:观察者(observer),一个或者多个,关注着目标对象的状态,例如上例的订阅了天气预报的人群。

 

三:观察者模式三种常见的角色场景:

      1. 一个目标对象,一个观察者对象,比如只要你一个人订阅了天气预报

      2. 一个目标对象,多个观察者对象,比如,你爸爸,你妈妈和你都订阅了天气预报

      3. 多个目标对象,一个观察者对象,比如你一个人订阅了天气预报,还订阅了报纸

 

四:推模型和拉模型(后面的代码会有注释):

      推模型:observer在执行update()方法时,获取的是subject传给它的具体参数,目标对象主动向观察者推送目标的详细信息。

      拉模型:observer在执行update()方法时,获得的是subject传给它的一个subject对象,observer需要什么参数自己去取。

 

五:java代码实行观察者模式:

     首先提供最基本的观察者模式代码框架:

     1. 新建一个Subject父类 

复制代码
import java.util.ArrayList;
import java.util.List;

/*
 * 目标对象,他知道观察它的观察者,并提供注册(添加)和删除观察者的接口
 */
public class Subject {
    //用来保存注册的观察者对对象
    private List<Observer> observers = new ArrayList<Observer>();
    
    //将观察者添加多list对象中
    public void attch(Observer observer){
         observers.add(observer);
    }
    
    //删除集合中的指定观察者对象
    public void delete(Observer observer){
        observers.remove(observer);
    }
    
    //向所有注册了的观察者通知消息
    protected void notifyObserver() {
        for(Observer observer:observers){
            observer.update(this);
        }
    } 
}
复制代码

  2. 新建一个具体Subject实现类

   
复制代码
/*
 * 具体的目标对象,负责把有关状态存入到相应的观察者对象
 */
public class ConcreteSubject extends Subject {
    //目标对象的状态
    private String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
        this.notifyObserver();
    }
    
}
复制代码

      3. 新建一个Observer接口

  

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

    4. 新建一个observer实现类

  

复制代码
/*
 * 具体的观察者对象,实现更新的方法,使自身状态和目标状态一致
 */
public class ConcreteObserver implements Observer {

    private String observerState;
    @Override
    public void update(Subject subject) {
        // TODO Auto-generated method stub
        observerState = ((ConcreteSubject)subject).getSubjectState();
    }
  
}
复制代码

 

    下面我用一个具体的例子,来实现观察者模式,让你更加清晰了解观察者模式   

    一个这样的场景,小东的女朋友和老妈都订阅了小东开发的一个天气预报软件,当每天天气不同时,小东的女朋友和老妈收到天气情况通知,都会安排明天的行程。小东的这个软件可逗的女朋友和老妈开心了,原来程序猿还有这作用,下面来看程序如何演示的:

          1. 新建一个WeatherSubject父目标对象

复制代码
import java.util.ArrayList;
import java.util.List;

/*
 * 目标对象,他知道观察它的观察者,并提供注册(添加)和删除观察者的接口
 */
public class WeatherSubject {
    //用来保存订阅天气的人
    private List<Observer> observers = new ArrayList<Observer>();
    
    //把订阅天气的人添加到订阅列表中
    public void attch(Observer observer){
         observers.add(observer);
    }
    
    //删除集合中的指定的订阅天气的人
    public void delete(Observer observer){
        observers.remove(observer);
    }
    
    //通知所有已经订阅了天气的人
    protected void notifyObserver() {
        for(Observer observer:observers){
            observer.update(this);
        }
    } 
}
复制代码

     2. 新建一个WeatherSubject具体实现对象( 观察者需要从目标对象中需要获取的的状态只有天气内容

复制代码
/*
 * 具体的目标对象,负责把有关状态存入到相应的观察者对象
 */
public class ConcreteWeatherSubject extends WeatherSubject {
    //获取天气的内容信息
    private String weatherContent;

    public String getWeatherContent() {
        return weatherContent;
    }

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

}
复制代码

     3. 新建一个Observer接口

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

    4. 新建一个具体的WeatherSubject对象

   

复制代码
/*
 * 具体的观察者对象,实现更新的方法,使自身状态和目标状态一致
 */
public class ConcreteObserver implements Observer {

    //观察者的名字,是谁收到了这个讯息,小东女朋友还是他老妈
    private String observerName;
    
    //天气内容的情况,这个消息从目标处获得
    private String weatherContent;
    
    //提醒的内容,小东的女朋友提醒约会,而他老妈提醒购物
    private String 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;
    }
    
    public void update(WeatherSubject subject) {
        weatherContent = ((ConcreteWeatherSubject)subject).getWeatherContent();
       System.out.println(observerName + "收到了" + weatherContent + ","+remindThing);
    }
  
}
复制代码

   5. 测试类

  

复制代码
public class Client {
   public static void main(String[] args) {
    //1.创建目标
       ConcreteWeatherSubject weatherSubject = new ConcreteWeatherSubject();
       
    //2.创建观察者
       ConcreteObserver observerGirl = new ConcreteObserver();
       observerGirl.setObserverName("小东的女朋友");
       observerGirl.setRemindThing("是我们的第一次约会,地点华罗利广场,不见不散额");
       
       ConcreteObserver observerMom = new ConcreteObserver();
       observerMom.setObserverName("小东的老妈");
       observerMom.setRemindThing("是一个购物的好日子,明天去老街血拼");
    //3.注册观察者
       weatherSubject.attch(observerGirl);
       weatherSubject.attch(observerMom);
       
    //4.目标发布天气
       weatherSubject.setWeatherContent("明天天气晴朗,晴空万里,温度28℃");
   }
}
复制代码

   6. 运行结果

     

 总结:

     各位程序猿屌丝们,原来观察者模式还能来泡妞,你还等什么了,现在对观察者模式有了基本的了解了吧。最后我们来谈谈哪些情况能用到观察者模式:

  • 当一个抽象模型有两个方面,其中一个方面的操作依赖与另一方面的状态变化就可以使用观察者模式。
  • 如果在更改一个状态的时候,需要同事连带改变其他对象,而且不知道有多少个对象需要被连带改变时,可以选用观察者模式。
  • 当一个对象必须通知其它对象,但你又希望这个对象和其它被它通知的对象是松散耦合的,也可以使用观察者模式。

     谢谢各位看官的赏脸,我们下次再见!

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

观察者模式(Observer Pattern)(三):使用java内置的支持实现HeadFirst气象站

一、问题描述 Weather-O-Rama气象站计划建立下一代的Internet气象观察站,该气象站必须建立在WeatherData对象的基础上,WeatherData对象提供天气数据,有三...

Java设计模式之观察者模式

本文继续介绍23种设计模式系列。介绍的是观察者模式。

Java设计模式——观察者模式

本文通过两个实例(分别是“气象观测站”和“计时器应用”),对Java设计模式中的观察者模式做一个详细的说明。...

用java代码实现观察者模式

/* 用java代码实现观察者模式, 前台负责观察老板在办公室还是离开并通知大家, 用观察者模式实现这一过程,请实现Guard类。 使最终输出结果为: “老板在办公室”   “前台通知大家:老板离开了...
  • zh521zh
  • zh521zh
  • 2015年11月17日 22:29
  • 768

Java语言提供的对观察者模式的支持

Java语言提供的对观察者模式的支持   在Java语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成Java语言对观察者模式的支持。   ...

Java 语言使用 Observer/Observable 实现简单的观察者模式

为了更好的理解什么是观察者模式,下面列举壹些可能用到该模式的情形或例子: (1)周期性任务。比如linux中的周期性任务命令crontab命令,win7 下的定时关机命令shutdown -s -t ...

责任链模式(java语言实现)

什么是责任链模式定义:在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处...
  • stuShan
  • stuShan
  • 2016年04月11日 23:49
  • 246

简单工厂模式(java语言实现)

1 工厂模式:百度百科: 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处...
  • stuShan
  • stuShan
  • 2015年10月14日 21:37
  • 251

用java语言实现事件委托模式

事件委托模式是一个比较常用的设计模式,但是Java语言本身没有对其做一定的封装,因此实现起来有一定难度(了解原理后很简单),相比之下.NET就容易了很多。 身为一个Java爱好者,怎么向这样一个小困难...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:码农成长计-观察者模式详解(java语言实现)
举报原因:
原因补充:

(最多只允许输入30个字)