博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java-设计模式-创建模式-观察者模式observer
阅读量:4030 次
发布时间:2019-05-24

本文共 6144 字,大约阅读时间需要 20 分钟。

java-设计模式-创建模式-观察者模式observer

一、什么时候用
    
当某个对象的状态发生改变时,你仍然需要对象之间能互相通信。但是出于各种原因,你也许并不愿意因为代码环境的改变而对代码做大的修改。
当一个对象的状态发生改变时,你如何通知其他对象?是否需要一个动态方案――一个就像允许脚本的执行一样,允许自由连接的方案。
    观测模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
二、实例
实例一:

Subject接口

public interface Subject {    public void registerObserver(Observer o);    public void removeObserver(Observer o);    public void notifyAllObservers();}

Observer接口

public interface Observer {    public void update(Subject s);}
Hunter类实现了Subject接口

import java.util.ArrayList; public class HeadHunter implements Subject{     //define a list of users, such as Mike, Bill, etc.    private ArrayList
userList; private ArrayList
jobs; public HeadHunter(){ userList = new ArrayList
(); jobs = new ArrayList
(); } @Override public void registerObserver(Observer o) { userList.add(o); } @Override public void removeObserver(Observer o) {} @Override public void notifyAllObservers() { for(Observer o: userList){ o.update(this); } } public void addJob(String job) { this.jobs.add(job); notifyAllObservers(); } public ArrayList
getJobs() { return jobs; } public String toString(){ return jobs.toString(); }}

JobSeeker是一个观察者:

public class JobSeeker implements Observer {     private String name;     public JobSeeker(String name){        this.name = name;    }    @Override    public void update(Subject s) {        System.out.println(this.name + " got notified!");        //print job list        System.out.println(s);    }}
开始使用:

public class Main {    public static void main(String[] args) {        HeadHunter hh = new HeadHunter();        hh.registerObserver(new JobSeeker("Mike"));        hh.registerObserver(new JobSeeker("Chris"));        hh.registerObserver(new JobSeeker("Jeff"));         //每次添加一个个job,所有找工作人都可以得到通知。        hh.addJob("Google Job");        hh.addJob("Yahoo Job");    }}

实例二:

 首先定义抽象的观察者:

//抽象观察者角色public interface Watcher{    public void update(String str);}
然后定义抽象的主题角色,即抽象的被观察者,在其中声明方法(添加、移除观察者,通知观察者):

//抽象主题角色,watched:被观察public interface Watched{    public void addWatcher(Watcher watcher);    public void removeWatcher(Watcher watcher);    public void notifyWatchers(String str);}

然后定义具体的观察者:
public class ConcreteWatcher implements Watcher{    @Override    public void update(String str)    {        System.out.println(str);    }}
之后是具体的主题角色:
 
import java.util.ArrayList;import java.util.List;public class ConcreteWatched implements Watched{    // 存放观察者private List
list = new ArrayList
(); @Override public void addWatcher(Watcher watcher) { list.add(watcher); } @Override public void removeWatcher(Watcher watcher) { list.remove(watcher); } @Override public void notifyWatchers(String str) { // 自动调用实际上是主题进行调用的for (Watcher watcher : list) { watcher.update(str); } }}
编写测试类:
public class Test{    public static void main(String[] args)    {        Watched girl = new ConcreteWatched();                Watcher watcher1 = new ConcreteWatcher();        Watcher watcher2 = new ConcreteWatcher();        Watcher watcher3 = new ConcreteWatcher();                girl.addWatcher(watcher1);        girl.addWatcher(watcher2);        girl.addWatcher(watcher3);                girl.notifyWatchers("开心");    }}
实例三: JDK实例
Client

    测试类。

NewsPublisher

    相当于ConcreteSubject角色。该类继承相当于Subject角色的java.util.Observable类。

SubscriberObserver

    相当于ConcreteObserver角色。该类实现了相当于Observer角色的java.util.Observer接口。当NewsPublisher对象发生变化时得到通知,并向订阅者发送订阅邮件。

ManagerObserver

    相当于ConcreteObserver角色。该类实现了相当于Observer角色的java.util.Observer接口。当NewsPublisher对象发生变化时得到通知,并向管理者发送消息邮件。

News

    封装了新闻数据的类,与Observer模式无直接关系。


代码:
import java.util.Observable;import java.util.Observer;public class Client {    /**     * Test Observer Pattern     * --     *      */    public static void main(String[] args) {        NewsPublisher publisher = new NewsPublisher();        //添加观察者对象        publisher.addObserver(new SubscriberObserver());        publisher.addObserver(new ManagerObserver());                //发布新闻,触发通知事件        publisher.publishNews("Hello news", "news body");    }}/*** Subject ROLE* NewsPublisher: news publisher**/class NewsPublisher extends Observable {    public void publishNews(String newsTitle, String newsBody) {        News news = new News(newsTitle, newsBody);        setChanged();       //通过setChanged()方法标明对象的状态已发生变化                System.out.println("News published:" + newsTitle);        this.notifyObservers(news);   //通知各Observer,并发送一个名为news对象的消息                //other process ... such as save news to database    }}/*** Observer ROLE* */class SubscriberObserver implements Observer {        public void update(Observable observee, Object param) {        if (param instanceof News) {            mail2Subscriber((News)param);        }    }        private void mail2Subscriber(News news) {        System.out.println("Mail to subscriber. A news published with title:" + news.getTitle());    }}/*** Observer ROLE* */class ManagerObserver implements Observer {        public void update(Observable observee, Object param) {        if (param instanceof News) {            mail2Manager((News)param);        }    }        private void mail2Manager(News news) {        System.out.println("Mail to Manager. A news published with title:" + news.getTitle());    }}//data entityclass News {    private String title;    private String body;        public News(String title, String body) {        this.title = title;        this.body = body;    }        public String getBody() {        return body;    }    public void setBody(String body) {        this.body = body;    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }}
执行Client,输出结果:
C:\Observer>javac *.java

C:\Observer>java Client

News published:Hello news

Mail to Manager. A news published with title:Hello news

Mail to subscriber. A news published with title:Hello news

实例二:

 首先定义抽象的观察者:

转载地址:http://gqqbi.baihongyu.com/

你可能感兴趣的文章
Oracle 物化视图
查看>>
PHP那点小事--三元运算符
查看>>
解决国内NPM安装依赖速度慢问题
查看>>
Brackets安装及常用插件安装
查看>>
在CentOS 7系统上搭建LNMP 环境
查看>>
Centos 7(Linux)环境下安装PHP(编译添加)相应动态扩展模块so(以openssl.so为例)
查看>>
fastcgi_param 详解
查看>>
Nginx配置文件(nginx.conf)配置详解
查看>>
标记一下
查看>>
一个ahk小函数, 实现版本号的比较
查看>>
IP报文格式学习笔记
查看>>
autohotkey快捷键显示隐藏文件和文件扩展名
查看>>
Linux中的进程
查看>>
学习python(1)——环境与常识
查看>>
学习设计模式(3)——单例模式和类的成员函数中的静态变量的作用域
查看>>
深度学习库安装与使用
查看>>
keras句子分类 keras_demo_for_sentence_classification (simplified version)
查看>>
MySQL for Windows 解压缩版配置安装
查看>>
MySQL必知必会(读书笔记)
查看>>
MySQL必知必会(读书笔记二)
查看>>