Java 设计模式-观察者模式(Observer)

写了两个关于设计模式的笔记之后突然感觉上瘾了,我的天啊,原来设计模式这么简单。隐隐约约觉得自己离架构师不远了,好开心,,,

“Ruffian,Ruffian,快醒醒,怎么博客写一半就睡着了,,,”。卧槽,是梦,是梦,,,

好吧,被叫醒了,那还是继续写博客吧。

今天记录一下观察这模式。先看看定义

观察这模式:对象间的一种一对多的依赖关系,一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。

诶,这个定义不错,简单明了,看字面意思就理解的差不多了,个人觉得还是有点抽象。

嗯,那么举个贴切生活的例子,微信公众号(CSDN大神鸿洋也曾使用这个来举例说明观察者模式,这里不排除笔者有抄袭的嫌疑,哈哈,不过对比网上这么多例子,还是觉得这个贴切,那就拿微信公众号来举例子说明 观察者模式 吧)

在互联网迅速发展的今天,微信这个大平台似乎成了一些商户宣传和推广自己产品的好渠道,例如深圳华强北某手机商户,开发了一个微信公众号,每天推送自己的新品手机,手机爱好者通过订阅公众号,可以接收到商户推送的消息,当然,哪天不喜欢了,就可以取消关注。

结合定义,

对象间的一种一对多的依赖关系

微信公众号跟关注者(手机爱好者)是一种一对多的关系

一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新

公众号推送了一条关于新品手机的消息,(一个对象发生了变化) ,关注者(依赖它的对象)就可以接收到推送过来的消息(都得到通知并自动刷新)。

观察者模式的定义真的很容易理解,特别结合微信公众号这个例子,如果你这都理解不了?卧槽,这都理解不了,那就只能通过代码来看看能不能帮到你了

首先创建一个微信公众号抽象类(主题类),不同类型的公众号从这里继承,然后各自实现自己的业务,然后创建一个观察者接口,所有的观察者实现这个接口。

主题类(公众号抽象类)

package cn.design.java.observer;

import java.util.ArrayList;
import java.util.List;

/**
 * 公众号抽象类<br/>
 * 所有公众号继承此类
 * 
 * @author Ruffian
 * @date 2016年5月13日
 * 
 */
public abstract class Subject {

    // 保存注册的观察者(保存所有关注公众号的用户)
    private List<Observer> observers = new ArrayList<Observer>();

    // 注册观察者(关注公众号)
    public void attach(Observer observer) {
        observers.add(observer);
    }

    // 删除观察者(取消关注)
    public void detach(Observer observer) {
        observers.remove(observer);
    }

    // 通知所有注册的观察者(推送消息给用户)
    public void nodifyObservers() {
        for (Observer observer : observers) {
            observer.update(this);
        }
    }

}

观察者(接口)

package cn.design.java.observer;

/**
 * 观察者接口<br/>
 * 所有观察者实现此接口
 * 
 * @author Ruffian
 * @date 2016年5月13日
 * 
 */
public interface Observer {

    /**
     * 更新接口
     * 
     * @param msg
     * @author Ruffian
     * @date 2016年5月13日
     */
    public void update(Subject subject);

}

仔细看代码,注释的很详细了。接下来我们创建一个具体主题的实现类(手机市场公众号),创建2个观察者具体实现类(手机爱好者),代码只是为了只管体现1对多的模式,不要太在意逻辑(这里我纯粹copy了一下)

具体主题的实现类(手机市场公众号)

package cn.design.java.observer;

/**
 * 主题实现类<br/>
 * 某个手机行业相关的公众号
 * 
 * @author Ruffian
 * @date 2016年5月13日
 * 
 */
public class PhoneSubject extends Subject {

    private double price;
    private String phone;

    // 设置推送信息(手机型号,价格)
    public void setPhoneMsg(String phone, double price) {
        this.phone = phone;
        this.price = price;
    }

    // 获取推送信息
    public String getPhoneMsg() {
        return "手机型号:" + phone + ",价格:" + price;
    }

    // 推送内容
    public void pushPhone() {

        System.out.println("公众号推送:" + getPhoneMsg());

        // 通知观察者
        nodifyObservers();

    }

}

观察者具体实现类(手机爱好者)

package cn.design.java.observer;

/**
 * 观察者实现类<br/>
 * 手机爱好者
 * 
 * @author Ruffian
 * @date 2016年5月13日
 * 
 */
public class PhoneFans1Observer implements Observer {

    @Override
    public void update(Subject subject) {

        // 接收到公众号推送的消息

        /**
         * update(Subject subject) <br/>
         * 备注: 参数可以设置为具体的消息(String),或者 Subject对象<br/>
         * 1.String:直接展示推送过来的消息 <br/>
         * 2.Subject:如果是Subject对象,则从Subject对象中获取需要的内容
         */

        String phoneMsg = ((PhoneSubject) subject).getPhoneMsg();

        // 展示消息
        System.out.println("粉丝1收到消息:" + phoneMsg);

    }

}
package cn.design.java.observer;

/**
 * 观察者实现类<br/>
 * 手机爱好者
 * 
 * @author Ruffian
 * @date 2016年5月13日
 * 
 */
public class PhoneFans2Observer implements Observer {

    @Override
    public void update(Subject subject) {

        // 接收到公众号推送的消息

        /**
         * update(Subject subject) <br/>
         * 备注: 参数可以设置为具体的消息(String),或者 Subject对象<br/>
         * 1.String:直接展示推送过来的消息 <br/>
         * 2.Subject:如果是Subject对象,则从Subject对象中获取需要的内容
         */

        String phoneMsg = ((PhoneSubject) subject).getPhoneMsg();

        // 展示消息
        System.out.println("粉丝2收到消息:" + phoneMsg);

    }

}

订阅者实现类创建了2个,公众号创建了1个,现在两个订阅者去订阅公众号,那么当公众号推送手机新品的时候,所有的订阅者都能接收到来自公众号的推送消息。

测试类

package cn.design.java.observer;

public class Test {
    public static void main(String[] args) {

        PhoneSubject subject = new PhoneSubject();
        Observer phoneFans1 = new PhoneFans1Observer();
        Observer phoneFans2 = new PhoneFans2Observer();

        // 手机爱好者关注公众号
        subject.attach(phoneFans1);
        subject.attach(phoneFans2);

        // 公众号编辑要推送的消息
        subject.setPhoneMsg("iPhone6s", 5288);
        // 推送消息
        subject.pushPhone();

    }
}

结果打印

输出结果

卧槽,这么简单明了的例子,要说的话在代码注释了都写完了,真不知道还能说些啥。看看代码吧。

看到这里Android开发者们有没有想到这个模式在安卓中哪里有用到呢?哎呀职业病,总是会想在Android哪里有运用。想到了吗?

没错就是广播!系统某个广播(例如手机开机启动广播),所有的APP都能注册广播接收器,来接受手机系统发出来的消息。

源码下载

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值