设计模式之观察者模式

观察者模式(Observer Pattern)属于行为型模式中的一种,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

当对象间存在一对多关系时,则使用观察者模式。比如:当一个对象被修改,状态发生改变时,则会自动通知它的依赖对象(即观察它的对象)。这是一种被动的观察,不是观察者不停地主动刷新去获取被观察者的状态,而是被观察者的状态发生改变时,去通知它的所有观察者。

模拟baby睡觉,妈妈发现她醒来之后就给她喂奶的过程

一对一的观察

//baby睡觉是一个独立的过程,故将其定义成一个线程任务
class Baby implements Runnable{
    Mother m=null;

    public Baby(Mather m){
        this.m=m;
    }
    @Override
    public void run() {
        try {
            for(int i=0; i<3; i++){//假设baby睡了三秒
                Thread.sleep(1000);
                System.out.println("baby is sleeping , "+i+" second");
            }
        }catch (InterruptedException e) {
            e.printStackTrace();
        }
        cryAndCallDady();//baby醒了,通知妈妈  
    }   
    //baby醒来时,通知她的观察者的方法
    public void cryAndCallDady(){
        System.out.println("baby醒了。。。。。");
        m.feetBaby();
    }
}
//观察者:妈妈
class Mother{
    public void feetBaby(){
        System.out.println("喂孩子吃奶");
    }
}

public class Test02{
    //用于模拟过程的主函数
    public static void main(String srgs[]){
        Mather m=new Mother();
        Baby baby=new Baby(m);
        Thread t1 = new Thread(baby);
        t1.start();
    }
}

//运行结果:
baby is sleeping , 0 second
baby is sleeping , 1 second
baby is sleeping , 2 second
baby醒了。。。。。
喂孩子吃奶

上边的代码组织方式存在很多问题,那就是当有多个观察者的时候,不能灵活的实现,而且,如果多个观察者需要对baby醒来的的这个事件做出不同反应时,每个反应对的方法也不同,还采用上边的模式很难实现,故要做以下修改。

一对多的观察者模式

class Baby implements Runnable{
    //保存baby的观察者们
    List<Observer> observers=new ArrayList<Observer>();

    public void addObserver(Observer obs){
        observers.add(obs);
    }
    @Override
    public void run() {
        try {
            for(int i=0; i<3; i++){
                Thread.sleep(1000);
                System.out.println("baby is sleeping , "+i+" second");
            }
        }catch (InterruptedException e) {
            e.printStackTrace();
        }
        wekeUp();//baby醒了,通知观察者们    
    }   
    //baby醒来通知每个观察者的方法
    public void wekeUp(){
        System.out.println("baby醒了。。。。。");
        for(Observer obs:observers){
            obs.doSomething();
        }
    }
}
//抽象出一个观察者接口,统一作出反应的方法
interface Observer{
    public void doSomething();
}
//不同的观察者对观察现象做自己不同的反应
class Mother implements Observer{
    @Override
    public void doSomething() {
        System.out.println("妈妈:喂孩子吃奶");
    }
}
class Grandmother implements Observer{
    @Override
    public void doSomething() {
        System.out.println("奶奶:逗孩子笑");
    }
}
class LittleDog implements Observer{
    @Override
    public void doSomething() {
        System.out.println("小狗:汪汪汪。。。");
    }
}

public class Test02{
    public static void main(String srgs[]){
        Baby baby=new Baby();
        //添加观察者
        baby.addObserver(new Mother());
        baby.addObserver(new Grandmother());
        baby.addObserver(new LittleDog());
        Thread t1 = new Thread(baby);
        t1.start();
    }
}

//运行结果:
baby is sleeping , 0 second
baby is sleeping , 1 second
baby is sleeping , 2 second
baby醒了。。。。。
妈妈:喂孩子吃奶
奶奶:逗孩子笑
小狗:汪汪汪。。。

上边就是一个常见的观察者模式示例了,如果我们需要针对被观察者也统一规范,可以再抽象出一个对应的接口来,然后让每个被观察者都实现该接口即可。

//被观察事物的抽象接口
interface Subject{
    List<Observer> observers=new ArrayList<Observer>();
    public void addObserver(Observer obs);//添加观察者
    public void delObserver(Observer obs);//删除观察者
    public void notify(Observer obs);//通知观察者
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值