码农成长计-观察者模式详解(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. 运行结果

     

 总结:

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

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

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

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

Java设计模式之观察者模式

本文继续介绍23种设计模式系列。介绍的是观察者模式。
  • jason0539
  • jason0539
  • 2015年04月16日 07:32
  • 29909

观察者模式 详解

定义 一个或多个观察者对目标的状态感兴趣,它们通过将自己依附在目标对象上以便注册所感兴趣的内容。 目标状态发生改变并且观察者可能对这些改变感兴趣,就会发送一个通知消息,调用每个观察者的更新方法。 当观...
  • u010388497
  • u010388497
  • 2016年06月18日 17:31
  • 526

Java设计模式(观察者模式JDK自带)

JDK自带的观察者模式和我们上一节说的基本相似,也有通用的观察协议规则 Observer,这个接口中只有一个方法,就是update方法 public interface Observer { ...
  • xyjwsj
  • xyjwsj
  • 2017年02月15日 16:47
  • 669

北漂码农的三年java开发工作感悟

又到了秋雨霏霏的时节,转眼之间已经在程序员这个职业滚爬了三年。   毕业于一所不入流的专科院校,没有任何的竞争优势,自己的年龄也不大,91年出生,可恨的是我面相长的成熟,我女友一直以来都喊我大叔...
  • u014744764
  • u014744764
  • 2014年09月26日 16:04
  • 1141

设计模式介绍之七:观察者模式(observer)

观察者模式(又称发布/订阅模式)定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新...
  • foruok
  • foruok
  • 2014年02月18日 19:55
  • 7305

通过Java源码分析初探观察者模式(一)

源码中,起关键性作用的就是vector和changed,在observable实例化的时候,就初始化了一个空的vector,可以通过vector添加和移除vector操作后,当observable发生...
  • pangpang123654
  • pangpang123654
  • 2016年05月30日 09:16
  • 6165

JAVA设计模式 之 观察者模式(JDK内置实现)

简介:使用JAVA内置的观察者模式
  • chengzhangmsdn
  • chengzhangmsdn
  • 2014年05月17日 19:27
  • 1931

码农上海工作2年感悟

不知不觉间已经毕业快2年了,想起2014年大学的最后一段时间,每天就是吃吃喝喝,宣泄着大学最后的时光。在大学的最后一个学期,得知自己保研了,心里面既高兴又很惆怅。高兴的是能够保研,说明自己大学4年确实...
  • polo_longsan
  • polo_longsan
  • 2016年02月27日 18:58
  • 1017

设计模式-深入解析观察者模式(Observer)

在上篇设计模式上我们继续前进把,苦逼(酷毙)的程序员一刻都不能松懈的,要紧跟脚步,每天都学习啊!!学了策略模式,我自己去用设计模式写了几个例子,感觉还扣以啊。下面继续总结一下观察者模式的学习,如有不正...
  • qq_29282475
  • qq_29282475
  • 2015年12月07日 16:16
  • 1243

一份中级程序员的简历

工作了几年,简历由简单到复杂,在到简单。有些感触。这份简历对于那些入行3-5年的程序员有些帮助。那么什么是一份不错的简历。我的答案有三点。1. 你要应聘什么职位。 2. 你能做哪些工作。 3. 你做过...
  • wzhiu
  • wzhiu
  • 2013年08月21日 17:52
  • 3143
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:码农成长计-观察者模式详解(java语言实现)
举报原因:
原因补充:

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