洞悉本质 | 论软件设计中间加一层的威力
为什么写这个主题?
软件设计中间加一层的解决方案,随处可见。写本文的目的也是因为看到很多场景都是基于这个思想的应用,就想着梳理一下,让大家看到一些本质的内容。
顺便以现今主流的一些技术或概念作为样本,进行拆解,辅助大家理解。
搞清底层逻辑和设计思想,才不会被各种技术名词,技术概念整的一脸懵逼。
现在铺天盖地的三高讲解、培训,千万悠着点学,别整的身体三高了,哈哈,开个玩笑。
但是软件的设计思想层面的东西,编程的一些思考,我们也需学习提升,思考沉淀。学技术不只有三高。
而且思维层面的东西不像学习个具体的技术框架,全身心投入个几天甚至几个小时就能上手使用了。而是需要一点一滴积累,一点一滴思考总结。
看别人的总结也不行,别人的永远是别人的,参考可以,一定要自己总结。
回归主题,今天分享的是「论软件设计中间加一层的威力」 。
正文开始
你熟悉的jvm
先看个jvm得简易执行图。
上图jvm部分是简化后的并不严谨,重点在整体结构上,可以看到,JVM处于class文件与操作系统之间。JVM针对不同操作系统做了实现。不同平台的JVM将class解释为对应平台的机器码执行。
通过在class与操作系统之间加上JVM之后,以后出现新的操作系统,只需要针对对应平台实现一套JVM(JVM的各平台实现是不需要我们关心的,有官方团队处理),项目即可在平台上运行,这便是Java宣称的一次编写,到处运行。到处运行的前提是,到处都需要有JVM的实现。
JVM在这里就充当了一个中间层,隔离了开发环境与操作系统。
隔离的好处是消除了双方之间直接接触带来的相互影响和不适应,这些都在JVM这一层化于无形。
对项目开发人员来说就不用关心底层是什么操作系统,我只对接JVM。操作系统的任何变化、升级都跟我无关,这都是JVM需要考虑的事。
对操作系统而言,也不需要因为要运行你的class而做出任何改变。这也是JVM需要考虑的事。
那些不知道在哪能用上的设计模式
代理模式
算是设计模式中比较简单也比较容易理解的一种,看个图。
加上中间的代理层后,对调用方来说并不知道实际类的真实情况,这样一方面可以隐藏实际类的信息,另一方面可以在代理层对调用方和实际类进行控制,可以做一些限制操作,又或者添加一些其他的处理逻辑,比如常见的在调用前后输出个日志。而这个处理过程对调用者和实际类来说是无感知的。
外观模式
同样先看个图
中间加了外观角色这个中间层后,对调用方来说,就变得简单了许多,原来哼哧哼哧调3个,现在简简单单调一个。
其他还有不少,限于篇幅,就不列举了。
消息中间件
这里主要说下用消息中间件解耦的场景,两个服务之间消除依赖,借助消息中间件即可实现,不用消息中间件可以实现吗,完全可以,自己实现一个中间的交换系统没什么不可以,只不过需要投入时间精力,所以大家都用现成的。
此场景下仅仅解耦两个服务之间的依赖其实是没什么可炫耀的,它真正的威力在于加了中间层后将多服务之间多对多的调用结构转换为了多对一结构。
如下图
右图比左图清楚的不是一点点,图能看清楚,代码实现就有了写清楚的前提。
网关
还是先看个图
加上网关这个中间层后,一方面可以隐藏真实服务的访问地址,另一方面对调用方来说统一了调用入口,同时可以在网关层统一对所有后端服务添加全局的处理逻辑,如鉴权、限流、日志记录等等。
最后再举个项目中的场景
之前项目中遇到的一个场景是,需要通过一个很复杂的统计SQL最终输出一个客户想要的结果,数据量较大时查询非常慢,在数据实时性要求不高,又不想引入多余技术组件的情况下,怎么处理这种问题 ?
解决办法就是加个中间结果表,定时执行统计SQL将结果输入到结果表,查询功能直接查询结果表,就很方便的解决了。处理过程如下图
以上仅仅列举了部分内容,没提到的就只能留给读者自行发觉领悟喽。
总结
结合上面的实例拆解,总结下,中间加一层的设计来说大概可以解决以下场景的问题。
这里特别强调下加一层是个设计思想,不光可以解决技术问题,工作中日常生活中也可以用到,所以关键的关键是需要吸收这种设计思想。
再回到技术场景下来说不同场景的处理方式会不一样,不一定是非要引入一个技术组件这样,比如某些特定场景下,加个字段,加个类都可以实现。一定要活学活用。
解耦
解耦的目的是为了后续可扩展,可维护,提升软件的可修改性,保证各自的独立进化。
聚合
为了简化上层调用和方便获取结果,添加一个聚合中间层,这里还是带一点解耦和隐藏细节的作用,虽说不是聚合的重点,但确有此功效。
统一处理
典型场景如上面提到的网关的应用场景和作用,如鉴权中心,日志记录等都可以在网关层统一去做。
隐藏细节
系统有没有自己的一些小秘密不想让外界知道,有怎么办 ?加上一个对外的调用层,隐藏真实服务地址,改变方法名,改变参数你想做的通通可以做到。
屏蔽差异
上面没提到的对应的场景,其实拿设计模式中的适配器来说这个比较合适,一个典型的场景是一个两插的插头如何接入到一个三口的插座上。中间加个转换头就可以做到。通过转接头间接屏蔽了接口间的差异。
对应到系统中也是如此,一个接口输出的是xml,而另一个接收方需要的是json,两方都不能改动情况下,怎么做,那就是加个中间转换层。屏蔽数据报文的差异。
最后
好的设计其实一定程度上可以避免一些技术问题,简化问题场景,而这需要我们不断摸索、不断尝试、不断学习、不断总结。
觉得还行,动动手指留个赞。
以上就是今天的内容,我们下期见。
更多优质内容,首发公众号【风象南】,欢迎关注。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
从1+1=2来理解Java字节码
背景 前不久《深入理解Java虚拟机》第三版发布了,赶紧买来看了看新版的内容,这本书更新了很多新版本虚拟机的内容,还对以前的部分内容进行了重构,还是值得去看的。本着复习和巩固的态度,我决定来编译一个简单的类文件来分析Java的字节码内容,来帮助理解和巩固Java字节码知识,希望也对阅读本文的你有所帮助。 说明:本次采用的环境是OpenJdk12 编译“1+1”代码 首先我们需要写个简单的小程序,1+1的程序,学习就要从最简单的1+1开始,代码如下: package top.luozhou.test; /** * @description: * @author: luozhou * @create: 2019-12-25 21:28 **/ public class TestJava { public static void main(String[] args) { int a=1+1; System.out.println(a); } } 写好java类文件后,首先执行命令javac TestJava.java 编译类文件,生成TestJava.class。 然后执行反编译命令jav...
- 下一篇
《吊打面试官》系列-ConcurrentHashMap & HashTable
你知道的越多,你不知道的越多 点赞再看,养成习惯 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试点思维导图,也整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。 前言 作为一个在互联网公司面一次拿一次Offer的面霸,打败了无数竞争对手,每次都只能看到无数落寞的身影失望的离开,略感愧疚(请允许我使用一下夸张的修辞手法)。 于是在一个寂寞难耐的夜晚,我痛定思痛,决定开始写互联网技术栈面试相关的文章,希望能帮助各位读者以后面试势如破竹,对面试官进行360°的反击,吊打问你的面试官,让一同面试的同僚瞠目结舌,疯狂收割大厂Offer! 所有文章的名字只是我的噱头,我们应该有一颗谦逊的心,所以希望大家怀着空杯心态好好学,一起进步。 回手掏 上次面试呀,我发现面试官对我的几个回答还是不够满意,觉得还是有点疑问,我就挑几个回答一下。 16是2的幂,8也是,32也是,为啥偏偏选了16? 我觉得就是一个经验值,定义16没有很特别的原因,只要是2次幂,其实用 8 和 32 都差不多。 用16只是因为作者认为16这...
相关文章
文章评论
共有0条评论来说两句吧...