浅谈Observer在代码中表现形式
说到观察者模式,基本在软件工程领域中是应用广泛,不知道的可以先学习一番,下面给个快速的回顾,然后在通过一个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在代码中表现形式的更多相关文章
- 浅谈线程池(中):独立线程池的作用及IO线程池
原文地址:http://blog.zhaojie.me/2009/07/thread-pool-2-dedicate-pool-and-io-pool.html 在上一篇文章中,我们简单讨论了线程池的 ...
- 【ASP.NET MVC系列】浅谈NuGet在VS中的运用
一 概述 在我们讲解NuGet前,我们先来看看一个例子. 1.例子: 假设现在开发一套系统,其中前端框架我们选择Bootstrap,由于选择Bootstrap作为前端框架,因此,在项目中,我们 ...
- 浅谈surging服务引擎中的rabbitmq组件和容器化部署
1.前言 上个星期完成了surging 的0.9.0.1 更新工作,此版本通过nuget下载引擎组件,下载后,无需通过代码build集成,引擎会通过Sidecar模式自动扫描装配异构组件来构建服务引擎 ...
- 浅谈如何检查Linux中开放端口列表
给大家分享一篇关于如何检查Linux中的开放端口列表的详细介绍,首先如果你想检查远程Linux系统上的端口是否打开请点击链接浏览.如果你想检查多个远程Linux系统上的端口是否打开请点击链接浏览.如果 ...
- 【Unity游戏开发】浅谈Lua和C#中的闭包
一.前言 目前在Unity游戏开发中,比较流行的两种语言就是Lua和C#.通常的做法是:C#做些核心的功能和接口供Lua调用,Lua主要做些UI模块和一些业务逻辑.这样既能在保持一定的游戏运行效率的同 ...
- 浅谈SQL Server数据内部表现形式
在上篇文章 浅谈SQL Server内部运行机制 中,与大家分享了SQL Server内部运行机制,通过上次的分享,相信大家已经能解决如下几个问题: 1.SQL Server 体系结构由哪几部分组成? ...
- 浅谈MFC类CrackMe中消息处理函数查找方法
最近一个学姐发给我了一份CrackMe希望我解一下,其中涉及到了MFC的消息函数查找的问题,就顺便以此为例谈一下自己使用的消息函数查找的方法.本人萌新,如果有任何错漏与解释不清的地方,欢迎各路大佬指正 ...
- 浅谈使用spring security中的BCryptPasswordEncoder方法对密码进行加密与密码匹配
浅谈使用springsecurity中的BCryptPasswordEncoder方法对密码进行加密(encode)与密码匹配(matches) spring security中的BCryptPass ...
- 浅谈如何使用代码为MP3文件写入ID3Tags
作者:郑童宇 GitHub:https://github.com/CrazyZty 1.前言 做了三年左右的Android开发,一直没写过博客,最近正好打算换工作,算是闲一些,就将以前开发所遇到的一些 ...
随机推荐
- Office Web Apps 2013 修改Excel在线查看文件大小限制
前言 最近搭建了一个OWA 2013环境,帮客户实现在线查看Excel文档,不过,使用过程中出现了错误,文件大小超过10MB就无法预览了,查了好久,发现需要使用PowerShell命令进行修改. 1. ...
- 一个简单的开源PHP爬虫框架『Phpfetcher』
这篇文章首发在吹水小镇:http://blog.reetsee.com/archives/366 要在手机或者电脑看到更好的图片或代码欢迎到博文原地址.也欢迎到博文原地址批评指正. 转载请注明: 吹水 ...
- 如何在VMware8虚拟机里安装Xp GHOST系统 解决不能启动Xp系统方法
好久没有装系统了.之前直接在硬盘中装,装个xp(c盘内).win7(d盘内).centos(虚拟机内)三系统同在一台笔记本电脑上.走了点弯路,这次记录下在虚拟机内装ghost xp. 安装步骤: 1. ...
- spring 整合junit进行测试
如果想让junit和spring容器环境无缝对接的话,可以使用如下方式: import com.jd.ptest.service.ICronService; import org.junit.Test ...
- Python装饰器用法
在Python中,装饰器一般用来修饰函数,实现公共功能,达到代码复用的目的.在函数定义前加上@xxxx,然后函数就注入了某些行为,很神奇!然而,这只是语法糖而已. 场景 假设,有一些工作函数,用来对数 ...
- 【转】Python3使用Django2.x的settings文件详解
# -*- coding:utf8 -*- import os # 项目路径 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__ ...
- 【Zookeeper】连接ZooKeeper的方式
使用客户端命令连接Zookeeper 连接Server 使用命令./zkCli.sh -server 127.0.0.1:2181 使用JAVA连接使用ZK POM添加引用 <dependenc ...
- PON
PON(Passive Optical Network:无源光纤网络). PON(无源光网络)是指(光配线网中)不含有任何电子器件及电子电源,ODN全部由光分路器(Splitter)等无源器件组成,不 ...
- [转]kindeditor隐藏上传图片框网络图片或本地上传的功能
原文地址:http://www.lingchenliang.com/post/154.html kindeditor富文本编辑器点击上传图片按钮,在弹出的窗口中去掉上传网络图片的功能,只留下本地上传, ...
- 通过动态SQL语句创建游标
DECLARE @sql varchar(100); DECLARE @TableName varchar(32); DECLARE @FieldName varchar(32); DECLARE @ ...