说到观察者模式,基本在软件工程领域中是应用广泛,不知道的可以先学习一番,下面给个快速的回顾,然后在通过一个grpc中的responseObserver谈下观察者对象在代码中的位置。

  喜欢类图,就不上其他图了,只有能看懂类图,才好说吗观察者在代码中的位置。但也要总结下观察者的消息事件对象:

  1、观察者订阅某个主题;

  2、主题发生变化,然后通知观察者

  3、观察着收到通知,然后作出响应

  这里涉及两类对象,观察者和被观察者(主题),首先第一步,观察者订阅某个主题,在业务领域,该行为动作应该由观察者自身发起的,但别扭的是,如上类图,注册这件事是由主题发起的,其实这样真的误导很多人,我们看Redis的发布订阅模式,其实类似观察者模式,但订阅这件事是由观察者发起的;

redis 127.0.0.1:> SUBSCRIBE redisChat

Reading messages... (press Ctrl-C to quit)
) "subscribe"
) "redisChat"
) (integer)

  如果按照DDD的思想,这类代码的编写其实要非常注重,因为和领域逻辑偏离一点,扯出来的维护工作可能就很大。

  那我们需要在观察者中加入注册/订阅这类代码吗?当然是不好的,因为一般注册这件事,在抽象程度上,不应该划分到任何一个类中,所以我们通常利用IOC思想,在第三方中做注册和订阅这件事,比喻下面的main方法类(你可以做成领域服务类);

  

public class Test {

    public static void main(String[] args) {
WechatServer server = new WechatServer(); Observer userZhang = new User("ZhangSan");
Observer userLi = new User("LiSi");
Observer userWang = new User("WangWu"); server.registerObserver(userZhang);
server.registerObserver(userLi);
server.registerObserver(userWang);
server.setInfomation("PHP是世界上最好用的语言!"); System.out.println("----------------------------------------------");
server.removeObserver(userZhang);
server.setInfomation("JAVA是世界上最好用的语言!"); }
}

  可以看到,观察者之所以在“观察”,是因为由个第三方帮它订阅了事件;下面我们看第三个例子,这个例子是我在grpc中看到的,如下:

  

    @Override
public void getFeature(Point request, StreamObserver<Feature> responseObserver) {
responseObserver.onNext(checkFeature(request));
responseObserver.onCompleted();
} ... private Feature checkFeature(Point location) {
for (Feature feature : features) {
if (feature.getLocation().getLatitude() == location.getLatitude()
&& feature.getLocation().getLongitude() == location.getLongitude()) {
return feature;
}
} // No feature was found, return an unnamed feature.
return Feature.newBuilder().setName("").setLocation(location).build();
}

  注意getFeature中的一个参数,称之为:responseObsever,他们叫,应答观察者,意思是,如果该远程调用的服务端做了什么事,请通知应答观察者对象,因为它需要做相应的行为,包括返回调用的结果;我们首先要知道,针对每一次RPC,该对象都是独一无二的,存在多个这样的对象,他们观察着各种感兴趣的事情(也就是我只实现了这些事件的应答,其他事情我不会谢谢),而这个时候,该对象的引用就在主题的代码中明显的完成这件事的操作;可见,如果你从代码中看待观察者是真的会乱七八糟的;

  从此可以看出,其实代码只是实现的方式,和实际的内存模型是有差别的;因此,各种设计模式都不能在代码和类图中学习,而是实际的把它们当作实体和对象;

  例如对于方法调用,代码看是写的混在一起,其实只是一种让计算机读懂的东西而已,在内存中的对象模型;其实方法调用,根本就是消息传递;指示者程序计数器的转动而已。

  例如,状态模式和策略模式,它们类图都非常相似,可是实质差别却非常大。

  最后总结一下:不要在代码中思考,任何设计,请把思维提高一层,用实体对象对待它们,代码只是计算机要读懂你的思维而已。

浅谈Observer在代码中表现形式的更多相关文章

  1. 浅谈线程池(中):独立线程池的作用及IO线程池

    原文地址:http://blog.zhaojie.me/2009/07/thread-pool-2-dedicate-pool-and-io-pool.html 在上一篇文章中,我们简单讨论了线程池的 ...

  2. 【ASP.NET MVC系列】浅谈NuGet在VS中的运用

    一     概述 在我们讲解NuGet前,我们先来看看一个例子. 1.例子: 假设现在开发一套系统,其中前端框架我们选择Bootstrap,由于选择Bootstrap作为前端框架,因此,在项目中,我们 ...

  3. 浅谈surging服务引擎中的rabbitmq组件和容器化部署

    1.前言 上个星期完成了surging 的0.9.0.1 更新工作,此版本通过nuget下载引擎组件,下载后,无需通过代码build集成,引擎会通过Sidecar模式自动扫描装配异构组件来构建服务引擎 ...

  4. 浅谈如何检查Linux中开放端口列表

    给大家分享一篇关于如何检查Linux中的开放端口列表的详细介绍,首先如果你想检查远程Linux系统上的端口是否打开请点击链接浏览.如果你想检查多个远程Linux系统上的端口是否打开请点击链接浏览.如果 ...

  5. 【Unity游戏开发】浅谈Lua和C#中的闭包

    一.前言 目前在Unity游戏开发中,比较流行的两种语言就是Lua和C#.通常的做法是:C#做些核心的功能和接口供Lua调用,Lua主要做些UI模块和一些业务逻辑.这样既能在保持一定的游戏运行效率的同 ...

  6. 浅谈SQL Server数据内部表现形式

    在上篇文章 浅谈SQL Server内部运行机制 中,与大家分享了SQL Server内部运行机制,通过上次的分享,相信大家已经能解决如下几个问题: 1.SQL Server 体系结构由哪几部分组成? ...

  7. 浅谈MFC类CrackMe中消息处理函数查找方法

    最近一个学姐发给我了一份CrackMe希望我解一下,其中涉及到了MFC的消息函数查找的问题,就顺便以此为例谈一下自己使用的消息函数查找的方法.本人萌新,如果有任何错漏与解释不清的地方,欢迎各路大佬指正 ...

  8. 浅谈使用spring security中的BCryptPasswordEncoder方法对密码进行加密与密码匹配

    浅谈使用springsecurity中的BCryptPasswordEncoder方法对密码进行加密(encode)与密码匹配(matches) spring security中的BCryptPass ...

  9. 浅谈如何使用代码为MP3文件写入ID3Tags

    作者:郑童宇 GitHub:https://github.com/CrazyZty 1.前言 做了三年左右的Android开发,一直没写过博客,最近正好打算换工作,算是闲一些,就将以前开发所遇到的一些 ...

随机推荐

  1. .net core使用配置文件

    .net core使用配置文件 在 .net core中,配置文件的读取是通过IConfiguration来提供的,程序集是Microsoft.Extensions.Configuration,对应的 ...

  2. python接口自动化测试(五)-其它(认证&代理&超时配置)

    有了前面几节的介绍,基本的接口测试是可以满足了.本节一些其它的高级技巧: 一.认证 1.基本认证: # -*- coding:utf-8 -*- import requests url = " ...

  3. Linux命令行烧录树莓派镜像至SD卡

    首先下载镜像压缩包 验证压缩包的未被串改 1 sha1sum 2013-09-25-wheezy-raspbian.zip 对此命令的输出结果和官网给出的SHA-1 Checksum进行比对,如果一致 ...

  4. vs2017 打开附带的localdb v13

    查看自己本机装了哪些版本的localdb 打开数据库资源管理器   添加数据库连接     选择要连接的localdb版本,这里选择的是v13版本      添加数据库   新建一个test数据库   ...

  5. html input 文本框 只能输入数字,包含输小数点.

    <input type="text" id="source_tds" name="source_tds" value="&l ...

  6. 使用PIP扩展BTARN

    下载安装部署 从GS1 US RosettaNet下载相应的PIP文件  新建BizTalk解决方案并设置签名 添加->现有项(C:\Program Files (x86)\Microsoft ...

  7. 应用间共享文件 FileProvider

    应用间共享文件 FileProvider 7.0及以上版本,分析文件给其他进程访问的时候,需要使用FileProvider,否则会出现崩溃: 例如:用系统下载器下载apk,然后通过Intent安装. ...

  8. (转)常用的 TCP KeepAlive 参数

    socket编程里通过setsockopt系统调用针对单独的socket进行设置,可以覆盖Linux Kernel的选项.举个例子,以我的系统默认设置为例,kernel默认设置的tcpkeepaliv ...

  9. Apache与php快速部署web服务

    [本文出自天外归云的博客园] 在一台服务器上临时起个web服务,读取服务器上的cfs文件内容并显示在页面上,做一个简单的web请求处理. 首先找到apache,在conf文件夹下vi httpd.co ...

  10. 学习笔记:The Log(我所读过的最好的一篇分布式技术文章)

    前言 这是一篇学习笔记. 学习的材料来自Jay Kreps的一篇讲Log的博文. 原文非常长.可是我坚持看完了,收获颇多,也深深为Jay哥的技术能力.架构能力和对于分布式系统的理解之深刻所折服.同一时 ...