说到观察者模式,基本在软件工程领域中是应用广泛,不知道的可以先学习一番,下面给个快速的回顾,然后在通过一个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. SharePoint 配置PowerShell任务计划

    前言 最近,有这么个需求,需要定时为SharePoint更新内容,所以,就想到了PowerShell命令和任务计划(Windows自带的功能,英文叫Task Schedule,在开始菜单里就能找到), ...

  2. 怎样让两个DIV在同一水平线上面显示

    css定义第二个div. float:right或者left. margin-top:0px 确保第二个DIV的宽度.如果宽度宽的话,会自动到下方的.

  3. SAP S/4 1610 IDES + HANA 2.0 安装

    前几天安装的都没带演示数据 ,这个版本带DEMO数据,学习比较好 我的机器配置: 内存:128G CPU:E5-2618L V4 硬盘:1T SSD 安装在VMware虚拟机中,安装完后,虚拟机大小只 ...

  4. CDH下集成spark2.2.0与kafka(四十一):在spark+kafka流处理程序中抛出错误java.lang.NoSuchMethodError: org.apache.kafka.clients.consumer.KafkaConsumer.subscribe(Ljava/util/Collection;)V

    错误信息 19/01/15 19:36:40 WARN consumer.ConsumerConfig: The configuration max.poll.records = 1 was supp ...

  5. MySql.Data.dll的版本

    在.Net下访问Mysql,先是用6.4.4,老有问题,也不知道哪个版本可以用,查询官网 https://dev.mysql.com/doc/connector-net/en/connector-ne ...

  6. 命令 上传项目到git中

    点击Clone or dowload会出现一个地址,copy这个地址备用. 接下来就到本地操作了,首先右键你的项目,如果你之前安装git成功的话,右键会出现两个新选项,分别为Git Gui Here, ...

  7. 【问题与解决】怎么删除TFS云端上的项目

    最近使用了Visual Stuidio提供的网络项目管理,感觉跟visual stuido结合起来还是很好用的,新建项目很简单,但是在删除项目的时候就没有那么简单了,直接通过VS的团队管理删除还会报错 ...

  8. Keras/Tensorflow选择GPU/CPU运行

    首先,导入os,再按照PCI_BUS_ID顺序,从0开始排列GPU, import os os.environ["CUDA_DEVICE_ORDER"] = "PCI_B ...

  9. TFS online build change web.config

    概要 TFS online 自动编译时如何修改web.config ref:https://dustinoprea.com/2016/05/06/using-tokenization-token-re ...

  10. Eclipse和MyEclipse使用技巧--解决MyEclipse中的js报错的小方法

    今天,下了个模版,但是导进去的时候发现js会报错.看了下其他都没有错误.而有一个js报错误,请原谅我有点红色强迫症,不能留一点红色 . 错误如下:Syntax error on token " ...