文档章节

设计模式之观察者模式

Lubby
 Lubby
发布于 2015/12/21 13:05
字数 649
阅读 70
收藏 2

观察者模式又称为发布订阅模式,里面角色分为观察者,被观察者。被观察者的动作会通知给注册的观察者。

现在设计一个故事,监狱里面有犯人和警察,警察会监控犯人的一举一动。当犯人吃饭的时候,警察会收到通知。

一、简单的观察者实现:

Observable:

public abstract class Observable {
    private Vector<Observer> obs = new Vector<>();

    public void notifyObs(Object param) {
        for (Observer ob : obs) {
            ob.update(param);
        }
    }

    public void addObserver(Observer ob) {
        this.obs.add(ob);
    }

    public void removeObserver(Observer ob) {
        this.obs.remove(ob);
    }

    public int getObserverSize() {
        return this.obs.size();
    }

    public boolean containObserver(Observer ob) {
        return this.obs.contains(ob);
    }
}

Observer:

public interface Observer  {
    void update(Object param);
}

Criminal:

public class Criminal extends Observable {
    public void eat(String food) {
        System.out.println("criminal is eating " + food);
        this.notifyObs(food);
    }
}

Police A:

public class PoliceA implements Observer {
    @Override
    public void update(Object param) {
        System.out.println("police A get message. param is "  + param);
    }
}

Police B:

public class PoliceB implements Observer {
    @Override
    public void update(Object param) {
        System.out.println("police A get message. param is "  + param);
    }
}

Test:

public class Test {
    public static void main(String[] args) {
        Criminal criminal = new Criminal();
        criminal.addObserver(new PoliceA());
        criminal.addObserver(new PoliceB());
        criminal.eat("西餐");
    }
}

上面的代码非常简单,很容易看懂。Observable是对观察者的抽象,里面有个Vectory,放入的是观察者。当有观察者注册的时候就放入到Vectory里面。Crimimal继承了Observable,当犯人吃饭的时候就依次通知Vectory里面的观察者。

JDK里面本身就存在Observable和Observer两个类,方便我们直接使用观察者模式。

二、使用JDK里面观察者的实现

Criminal:

public class Criminal extends Observable {

    public void eat(String food) {
        System.out.println("criminal eat " + food);
        super.setChanged();
        notifyObservers("criminal is eating " + food);
    }
}

Police A:

public class PoliceA implements Observer{
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("Police A watch : " + arg);
    }
}

Police B:

public class PoliceB implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("Police B watch . " + arg);
        System.out.println(o);
    }
}

Test:

public class Test {
    public static void main(String[] args) {
        Criminal criminal = new Criminal();
        criminal.addObserver(new PoliceA());
        criminal.addObserver(new PoliceB());
        criminal.eat("川菜");
    }
}


二、观察者模式的缺点

  1. 当某些观察者执行时间过长,会导致后面的观察者过长的延迟.  

    解决办法:使用异步处理,无论是在观察者端通知的步骤使用异步还是被观察者收到通知然后执行的步骤使用异步,都可以.

  2. 观察者同时也可以是被观察者。广播链太长,可维护性很差。


© 著作权归作者所有

共有 人打赏支持
Lubby
粉丝 54
博文 92
码字总数 49445
作品 0
杭州
程序员

暂无文章

centos7安装rsync及两台机器进行文件同步

centos7安装rsync及两台机器进行文件同步 2017年12月21日 11:17:46 码农下的天桥 阅读数:2210 标签: centosrsync同步 更多 个人分类: 后端 所属专栏: 研发模式及运维 版权声明:本文为博...

linjin200
19分钟前
1
0
jpg、jpeg、png... 的区别

jpg、jpeg、png... 的区别 对于做设计这一行的人来说,这几个图片格式是最常用的,也是最常见的,几乎每一天都要与他们打交道。 刚刚入门的新人通常不知道在什么地方如何使用他们或者说如何更...

DemonsI
38分钟前
5
0
白话SpringCloud | 第十章:路由网关(Zuul)进阶:过滤器、异常处理

前言 简单介绍了关于Zuul的一些简单使用以及一些路由规则的简单说明。而对于一个统一网关而言,需要处理各种各类的请求,对不同的url进行拦截,或者对调用服务的异常进行二次处理等等。今天,...

oKong
43分钟前
2
0
Character的static方法

基本类型char的包装类是Character,使用的比较多,大家是比较熟悉的。 我只是觉得里面有很多static方法,平时不怎么用,学习一下怎么实现的,或许日后就用到了。 static int compare(char x,...

woshixin
56分钟前
2
0
正则介绍_sed

10月17日任务 9.4/9.5 sed sed工具 匹配打印 -n 只打印匹配行,不然其他行也会打印出来 p 打印(配合-n使用) [root@centos7 tmp]# sed -n '/root/'p passwd root:x:0:0:root:/root:/bin/ba...

robertt15
56分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部