Java设计模式之观察者模式

一、概念描述

观察者模式属于行为型模式,其意图是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
这一个模式的关键对象是目标(Subject)和观察者(Observer)。一个目标可以有任意数目的依赖它的观察者,一旦目标的状态发生改变,所有的观察者都得到通知,作为对这个通知的响应,每个观察者都将查询目标以使其状态与目标的状态同步。

二、适用场景

观察者模式,用于存在一对多依赖关系的对象间,当被依赖者变化时,通知依赖者全部进行更新。因此,被依赖者,应该有添加/删除依赖者的方法,且可以将添加的依赖者放到一个容器中;且有一个方法去通知依赖者进行更新。

三、观察者模式的结构

观察者模式

观察者模式所涉及的角色有:

抽象主题(Subject)角色:抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。

具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。

抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。

具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。

四、一个实例

老师有一个电话号码,学生需要知道老师的电话号码以便于在需要的时候拨打,当老师的电话号码发生改变时,学生得到通知,并更新相应的电话记录。在这样的组合中,老师就是一个被观察者(Subject),学生就是需要知道信息的观察者(Observer)。

源码:

抽象主题(Subject)角色:

package com.test.observer;

public interface Subject {

    public void attach(Observer o);
    public void detach(Observer o);

    public void notice();

}

具体主题(ConcreteSubject)角色:

package com.test.observer;

import java.util.Vector;

public class Teacher implements Subject{

    private String phone;
    private Vector students;

    public Teacher() {
        phone = "";
        students = new Vector();
    }

    @Override
    public void attach(Observer o) {
        students.add(o);

    }

    @Override
    public void detach(Observer o) {
        students.remove(o);

    }

    /**
     * 当目标状态发生改变时,发布通知给观察者
     */
    @Override
    public void notice() {
         for(int i=0;i<students.size();i++){
             ((Observer)students.get(i)).update();
         }

    }

    public void setPhone(String phone) {
        this.phone = phone;
        notice();
    }

    public String getPhone() {
        return phone;
    }

}

抽象观察者(Observer)角色:

package com.test.observer;

public interface Observer {

    public void update();
}

具体观察者(ConcreteObserver)角色:

package com.test.observer;

public class Student implements Observer{

    private int student_id;
    private String teacher_phone;

    private Teacher teacher;

    public Student(int student_id,String teacher_phone) {
        // TODO Auto-generated constructor stub
        this.student_id = student_id;
        this.teacher_phone = teacher_phone;

    }
    public Student(int student_id,Teacher teacher) {
        // TODO Auto-generated constructor stub
        this.student_id = student_id;
        this.teacher = teacher;
    }

    /**
     * 当收到目标通知后更新
     */
    @Override
    public void update() {

        teacher_phone = teacher.getPhone();

    }

    public void show(){
        System.out.println("id:"+ student_id + "  teacher_phone:"+teacher_phone);
    }

}

测试主类:

package com.test.observer;

import java.util.Vector;

public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Vector students = new Vector();

        Teacher teacher = new Teacher();

        for(int i=0;i<10;i++){
            Student student = new Student(i,teacher);
            students.add(student);
            teacher.attach(student);
        }

        teacher.setPhone("10086-123");
        for(int i=0;i<10;i++){
            ((Student)students.get(i)).show();
        }

    }

}

运行结果:

id:0  teacher_phone:10086-123
id:1  teacher_phone:10086-123
id:2  teacher_phone:10086-123
id:3  teacher_phone:10086-123
id:4  teacher_phone:10086-123
id:5  teacher_phone:10086-123
id:6  teacher_phone:10086-123
id:7  teacher_phone:10086-123
id:8  teacher_phone:10086-123
id:9  teacher_phone:10086-123

Observer模式的最知名的应用是在MVC结构,Observer模式可以很好的应用在文档和图表程序的制作中。

参考:
http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html

http://www.cnblogs.com/hnrainll/archive/2011/12/29/2305582.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值