你手机中的观察者模式-阿里云开发者社区

开发者社区> 小弟的谷哥> 正文

你手机中的观察者模式

简介: 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程0...
+关注继续查看

自定义View系列教程00–推翻自己和过往,重学自定义View
自定义View系列教程01–常用工具介绍
自定义View系列教程02–onMeasure源码详尽分析
自定义View系列教程03–onLayout源码详尽分析
自定义View系列教程04–Draw源码分析及其实践
自定义View系列教程05–示例分析
自定义View系列教程06–详解View的Touch事件处理
自定义View系列教程07–详解ViewGroup分发Touch事件
自定义View系列教程08–滑动冲突的产生及其处理


探索Android软键盘的疑难杂症
深入探讨Android异步精髓Handler
详解Android主流框架不可或缺的基石
站在源码的肩膀上全解Scroller工作机制


Android多分辨率适配框架(1)— 核心基础
Android多分辨率适配框架(2)— 原理剖析
Android多分辨率适配框架(3)— 使用指南


版权声明


引子

做Android开发的童鞋都知晓目前在开发中最流行的套餐RxJava+Retrofit。嗯哼,前两天和同事吃饭,他无意间提起一个异步的问题;我说:可以用RxJava试试。这个哥们放下筷子,一本正经地告诉我:别用那玩意,不好用。

“不好用?”我疑惑地问到
“嗯”
“怎么不好用了?”
“反正就是感觉有点怪,一会儿观察,一会儿被观察,搞不清楚”

嗯嗯,听他说完这些,我大概明白了:他对RxJava的困惑其实是源于对观察者模式的陌生。没事儿,我们按照以往的套路来一起学习观察者模式。


观察者模式详细示例

在正式进入该设计模式之前,我想问一下:你们平常都用微信干什么呢?

“聊天”
“发朋友圈”
“逛微店”
“约…..”

好了,打住,我知道你想说什么了;再说下去我就要打马赛克了。你想想还有别的么?

“别的?除了这些,我还看微信公众号,关注自己喜欢的内容”

好嘞,就从微信公众号入手!平常我们关注一个微信公众号,当它推送新内容时,手机界面上就会出现一个红色的小点提醒我们查看详细内容。换句话说:我们订阅了公众号,当它有新消息时就会自动告知我们。再说得通俗点:相当于我们自己是观察者,在观察微信公众号,公众号就是被观察者。现在,我们用代码来模拟这个过程:

package cn.com;

/**
 * 原创作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */

public interface Subscription {
    public void addUserAccount(UserAccount userAccount);
    public void deleteUserAccount(UserAccount userAccount);
    public void sendMessage(String message);
}

建立抽象的被观察者

package cn.com;

import java.util.ArrayList;

/**
 * 原创作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */

public class SubscriptionAccount implements Subscription{
    private ArrayList<UserAccount> userAccountArrayList;

    public SubscriptionAccount(){
        userAccountArrayList=new ArrayList<>();
    }

    @Override
    public void addUserAccount(UserAccount userAccount) {
        if (userAccount!=null){
            userAccountArrayList.add(userAccount);
        }
    }

    @Override
    public void deleteUserAccount(UserAccount userAccount) {
        if (userAccount!=null){
            userAccountArrayList.remove(userAccount);
        }
    }

    @Override
    public void sendMessage(String message) {
        if(message!=null){
            for(UserAccount userAccount:userAccountArrayList){
                userAccount.receiveMessage(message);
            }
        }
    }
}

具体的被观察者,也就是刚才提到的微信公众号实现抽象被观察者。在此模拟微信公众号几个常用的方法:添加用户,删除用户,发送消息。

package cn.com;

/**
 * 原创作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */

public interface User {
    public void receiveMessage(String message);
}

抽象观察者。

package cn.com;

/**
 * 原创作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */

public class UserAccount implements User{

    private String name;

    public UserAccount(String name){
        this.name=name;
    }
    @Override
    public void receiveMessage(String message) {
        System.out.println(name+",收到消息:"+message);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

具体的观察者实现抽象观察者,也就是微信公众号的订阅者,比如我们自己。好了,现在微信公众号有了,用户也有了,我们来测试一把:

package cn.com;
/**
 * 原创作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
public class Test {

    public static void main(String[] args) {
          SubscriptionAccount subscriptionAccount=new SubscriptionAccount();
            UserAccount userAccount1=new UserAccount("老王");
            UserAccount userAccount2=new UserAccount("小弟");
            UserAccount userAccount3=new UserAccount("包包");
            subscriptionAccount.addUserAccount(userAccount1);
            subscriptionAccount.addUserAccount(userAccount2);
            subscriptionAccount.addUserAccount(userAccount3);
            subscriptionAccount.sendMessage("有心课堂新课程上线啦");

    }

}
  • 创建三个用户,老王,小弟,包包
  • 微信公众号添加这三个用户
  • 微信公众号发布消息

请看,控制台输出日志:

老王,收到消息:有心课堂新课程上线啦
小弟,收到消息:有心课堂新课程上线啦
包包,收到消息:有心课堂新课程上线啦

嗯哼,看到了么?三个微信用户都收到了微信公众号发布的消息。我们平常订阅微信公众号的本质是:微信公众号记录下我们的微信账号。所以,当它有新消息推送时瞅瞅自己的小本子上记录了谁就发送给谁。

看完这个小例子,我们再来梳理一下观察者模式。

  • 该模式中存在观察者和被观察者
  • 观察者和被观察者通过订阅发生关联关系
  • 当被观察者发出消息后,所有观察者均会收到消息

OK,当你看完了这个例子,再看RxJava的代码:

observable.subscribe(observer);

是不是就反应过来了呢?很多初学者看到这句代码的时候都会抓狂:怎么会是被观察者订阅了观察者?!!不该是观察者订阅被观察者么?!!其实,不必过于纠结文字表述的细节,重要的是明白其中的思想,它和我们刚才的:

  subscriptionAccount.addUserAccount(userAccount);

难道不一样么?就是同一回事!没啥不同的。我们在思考问题的时候,不能单纯地只站在生活的角度来看,也不能光从计算机的角度来考虑;而是要把两者结合起来,不要钻牛角尖,认死理。


小感悟

很多刚开始做开发的童鞋喜欢拿着一本厚厚的设计模式在角落里默默地啃。学习的劲头很足,态度也很端正,配得上10086个赞。在此,我也想提醒一下小伙伴们:学习态度和努力程度固然非常重要,但是我们也要注意学习方法。抛开实际应用和业务逻辑单纯地看设计模式是很难理解其精髓的。我们不妨将设计模式和自己的实际工作结合起来学习,比如做Android开发的小伙伴可结合Android源码或者非常流行的第三方库来深入地研究设计模式,在此推荐一篇《Retrofit分析-漂亮的解耦套路》供大家学习参考


参考资料

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10095 0
使用NAT网关轻松为单台云服务器设置多个公网IP
在应用中,有时会遇到用户询问如何使单台云服务器具备多个公网IP的问题。 具体如何操作呢,有了NAT网关这个也不是难题。
26797 0
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
11638 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
9161 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13893 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
7365 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
4510 0
+关注
小弟的谷哥
welcome
766
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载