面向过程(函数)、面向对象、面向接口、面向组件、面向服务、面向微服务,这几个词,好多人傻傻分不清楚。让俺来回归原教旨主义,给大家析辨析辨。正好这些阶段咱都亲身经历过,没有从90年代初期开始编程的人,可能没啥切肤体会到。
一、面向过程(函数)
我们发现,一个函数的输入输出变化了,很多关联调用都要修改。所以我们提出面向过程(函数),好好的设计函数的输入输出。
二、面向对象
我们发现,不少函数其实是有一定组织关系的,但是在面向过程(函数)编程过程中,这些函数都是平行排列的,没有显性化组织。
所以我们发明面向对象,同一个对象关联的函数组织在一起,并且哪些函数是私有的,哪些是公有的,哪些是亲兄弟才能半公开调用的。
三、面向接口
我们发现有以下变化:
1、架构师这一个岗位被提出来了,专门用于框架性代码的设计。架构师和程序员是两个岗位了。架构师他们不关心具体实现,他们特别关心对象和对象之间的关系、层与层之间的关系。这样,定义和实现要求分离。
2、我们也发现,我和你不是一个项目组的,你想调用我的类,但是我不想给你这个类的源代码实现,因为我的这个类的源代码的所有权归我,我可能需要随时变化它,但我和你商定好的调用接口,我们保持稳定,我只需要给你合规的输入输出,你别管我内部代码怎么改。
因而,面向接口编程出现了。它既是类特征,又做到了定义和实现的分离。
四、面向组件
组件比对象更进一步。这里面关键的差异就是:组件是有容器的,对象和类是没有容器的。组件的生命周期是由容器来决定的,而对象,需要程序员自己管理对象的生死创建与回收。
显然,组件更让程序员省心。因为内存管理,对于大量的程序员都是个挑战。这又把编程难度拉下一个门槛。
小结:这里出现了组件容器中间件服务器
五、面向服务
服务比接口更进一步。
虽然组件编程已经具备了容器化,虽然面向接口编程已经做到了定义和具体实现的分离。
但我们还差一步,就是接口应该和开发语言无关。所谓的接口,不外乎就是参数的输入输出。但输入输出是有类型的。比如说,有的语言是面向对象的,你定义了一个输出参数是个对象的,当然这没问题。但如果调用方是不面向对象的语言,你咋办?
这就是面向接口编程当年留下的后遗症,和开发语言强相关。
如何和开发语言不强相关,这就是面向服务要解决的。
所以,面向服务在输入输出参数方面利用了结构化文本这一东西,在参数传递方面利用了文本传输协议。比如说:XML/JSON、HTTP REST/WebService。当然,怎么传数据也可以随便,可以用消息队列(同步异步皆可),也可以用TCP等等。只不过协议需要定义好怎么建立握手、怎么响应、怎么处理容错、怎么处理安全等等,这都是需要协议定义好的。
现在有企业服务总线,你想用啥输入输出表示格式都行,你想用啥传输协议都行,根据你组件的质量保证要求就OK。当然,你说你的代码简单,不需要企业服务总线,两个组件之间通过服务直接调用了,那也OK,那就不需要企业服务总线了。
小结:这里出现了企业服务总线中间件。
六、面向微服务
我们解决了接口与开发语言的无关性,我们的组件就可以由不同语言来实现,而且之间能通畅调用,通过各种近程远程协议我们还能实现跨进程跨服务器之间的调用。
当时我们这时又遇到了一个棘手问题,就是各个语言实现的组件,需要依赖的框架和库越来越多,而且这些框架和库的版本还有时候打架。你经常会发现,你用的这个框架要依赖2.3版本,另外一个东西非要依赖2.2版本(可能作者懒了不更新了)。而如果2.3和2.2之间的函数接口不一致了,而且作者也没保证平滑升级,那就不能升级统一版本。
咋办?为了防止版本打架,只能把这些组件隔离开。幸好现在出现了Docker技术,可以在一台物理机上不用安装N个笨重的虚拟机(虚拟机要操作系统一堆东西),只需要安装好Docker,组件以及组件关联的各种框架类库就被隔离开了。
小结:这里出现了Docker容器中间件。