了解23种设计模式之观察者模式

一,什么是观察者模式。

Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。

Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。

二,观察者模式的结构。

三,观察者模式的角色和职责

Subject(被观察者)

     被观察者的对象。当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。Subject 需要维持(通知,删除,添加) 一个观察者对象的队列列表。

ConcreteSubject

      被观察者的具体实现。包含一些基本的属性状态及其他操作。

Observer (观察者)

      接口或抽象类。当Subject 的状态发生变化时,Observer 对象将通过一个 callback函数得到通知。

ConcreteObserver

    观察者的具体实现。得到通知后将完成一些具体的业务逻辑处理。

 具体 jdk -api:

被 观察者 继承 Observble

观察者 实现 Observer 接口

 

观察者模式的典型应用

Observer 模式的典型应用

--侦听事件驱动程序设计中的外部事件

--侦听/监视某个对象的状态变化

--发布者/订阅者(publisher/subscriber)模型中,当一个外部事件(新的产品,消息的出现等等)被触发。通知邮件列表中的订阅者。

 

四:例子代码实现

此类表示模型视图范例中的 observable 对象,或者说“数据”。可将其子类化,表示应用程序想要观察的对象。

一个 observable 对象可以有一个或多个观察者。观察者可以是实现了 Observer 接口的任意对象。一个 observable 实例改变后,调用 ObservablenotifyObservers 方法的应用程序会通过调用观察者的 update 方法来通知观察者该实例发生了改变。

未指定发送通知的顺序。Observable 类中所提供的默认实现将按照其注册的重要性顺序来通知 Observers,但是子类可能改变此顺序,从而使用非固定顺序在单独的线程上发送通知,或者也可能保证其子类遵从其所选择的顺序。

注意,此通知机制与线程无关,并且与 Object 类的 wait 和 notify 机制完全独立。

新创建一个 observable 对象时,其观察者集是空的。当且仅当 equals 方法为两个观察者返回 true 时,才认为它们是相同的。(来自 jdk --api)

4.1.被观察者

/**
 * @ClassName Person
 * @Description  继承 Observable 表示可以被观察的
 *
 * @Version 1.0
 **/
public class Person extends Observable {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
        //当 name 属性改变,  标记此 被观察 对象为已改变的对象;现在 hasChanged 方法将返回 true。默认为true。
        this.setChanged();
        // 通知 观察者
        this.notifyObservers();
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;

        //当 name 属性改变, 设置为 true ,默认为true.  标记此 被观察 对象为已改变的对象;现在 hasChanged 方法将返回 true。
        this.setChanged();
        // 通知 观察者
        this.notifyObservers();
    }
}

4.2 观察者

/**
 * @ClassName MyObServer
 * @Description 观察者, 一个可在观察者要得到 observable 对象更改通知时可实现 Observer 接口的类。
 * @Version 1.0
 **/
public class MyObServer  implements Observer {

    /**
     *只要改变了 observable 对象就调用此方法。应用程序调用 Observable 对象的 notifyObservers 方法,以便向所有该对象的观察者通知此改变。
     * @param o
     * @param arg
     */
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("对象发生改变");
    }
}

4.3 测试

public class Test {
    public static void main(String[] args) {
        Person person =new Person();
        //注册1号观察者
        person.addObserver(new MyObServer());
        //注册2号观察者
        person.addObserver(new MyObServer());
        person.setName("张三");
    }
}

五, 实际应用实现。

定义一个消息者对象

/**
 * @ClassName Article
 * @Description TODO
 * @Version 1.0
 **/
public class Article {
    private String articleTitle;
    private String articleContent;

    public String getArticleTitle() {
        return articleTitle;
    }

    public void setArticleTitle(String articleTitle) {
        this.articleTitle = articleTitle;
    }

    public String getArticleContent() {
        return articleContent;
    }

    public void setArticleContent(String articleContent) {
        this.articleContent = articleContent;
    }
}

定义一个被侦听/监视  消息者对象的状态变化,发布者/订阅者(publisher/subscriber)模型中,当一个外部事件(新的产品,消息的出现等等)被触发。通知邮件列表中的订阅者。

/**
 * @ClassName BlogUser
 * @Description TODO
 * @Version 1.0
 **/
public class BlogUser extends Observable {


    public void publishBlog(String articleTitle, String articleContent) {
        Article art = new Article();
        art.setArticleTitle(articleTitle);
        art.setArticleContent(articleContent);
        this.setChanged();
        this.notifyObservers(art);

    }
}

定义个 观察者 ,相当于订阅者。

/**
 * @ClassName MyObServer
 * @Description 观察者, 一个可在观察者要得到 observable 对象更改通知时可实现 Observer 接口的类。
 * @Version 1.0
 **/
public class MyObServer  implements Observer {

    /**
     *只要改变了 observable 对象就调用此方法。应用程序调用 Observable 对象的 notifyObservers 方法,以便向所有该对象的观察者通知此改变。
     * @param o
     * @param arg
     */
    @Override
    public void update(Observable o, Object arg) {
        Article art = (Article) arg;
        System.out.println("博主发表了文章");
        System.out.println("博客标题为:"+art.getArticleTitle());
        System.out.println("博客内容为:"+art.getArticleContent());
    }
}

测试

/**
 * @ClassName Test
 * @Version 1.0
 **/
public class Test {
    public static void main(String[] args) {

       Article art = new Article();
       BlogUser blogUser = new BlogUser();
       blogUser.addObserver(new MyObServer());
       blogUser.publishBlog("博客上线了","大家来访问");
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可乐cc呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值