架构思维:抽象分层分治演化

Posted 爪哇岛主

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了架构思维:抽象分层分治演化相关的知识,希望对你有一定的参考价值。

架构思维:抽象、分层、分治、演化

互联网的精髓就是共享,可以共享技术、共享经验、共享情感、共享快乐~

很多年前就有这个想法了,从事IT行业时间也不短了,应该把自己工作和业余所学习的东西记录并分享出来,和有缘人一起学习和交流。

如果您是那个有缘人,请上岛一叙!爪哇岛随时欢迎您!


一、总述架构

  1. 架构的本质是管理复杂性,抽象、分层、分治和演化架构的本质是管理复杂性,抽象、分层、分治和演化 是应对和管理复杂性的四种最基本武器。
  2. 对思维习惯和思考能力的培养,其重要性远远大于对实际技术工具的掌握。

二、抽象思维

  1. 抽象(abstraction)这个词大家经常听到,但是真正理解和能讲清楚什么是抽象的人少之又少。抽象其实是这样定义的:对某种事物进行简化表示或描述的过程,抽象让我们关注要素,隐藏额外细节
  2. 在系统架构和设计中,抽象帮助我们从大处着眼(get our mind about big picture),隐藏细节(temporarily hide details)。抽象能力的强弱,直接决定我们所能解决问题的复杂性和规模大小。
    image
    搭积木的时候,小朋友脑袋里头先有一个城堡的大图(抽象),然后他/她大脑里头会有一个初步的子模块分解(潜意识中完成),接着用利用积木搭建每一个子模块,最终拼装出最后的城堡
  3. 架构师先要在大脑中形成抽象概念,然后是子模块分解,然后是依次实现子模块,最后将子模块拼装组合起来,形成最后系统。 优秀的架构师受职业习惯影响,眼睛里看到的世界都是模块化拼装组合式的。抽象能力不仅对软件系统架构设计重要,对建筑、商业、管理等人类其它领域活动同样非常重要。其实可以这样认为,我们生存的世界都是在抽象的基础上构建起来的,离开抽象人类将寸步难行。
  4. 有经验的程序员写代码会保持抽象层次的一致性,代码读起来像讲故事,比较清晰易于理解;而没有经验的程序员会有明显的抽象层次跳跃问题,代码读起来就比较累,这个是抽象能力不足造成。
    image
    上述流程中的抽象是在同一个层次上的,比较清晰易于理解,但是没有经验的程序员在实现这个流程的时候,代码层次会跳,比方说主流程到支付卡校验一块,他的代码会突然跳出一行某银行API远程调用,这个就是抽象跳跃,银行API调用是细节,应该封装在PaycardVerification这个抽象里头。

三、分层思维

  1. 构建一套复杂系统,我们把整个系统划分成若干个层次,每一层专注解决某个领域的问题,并向上提供服务
    有些层次是纵向的,它贯穿所有其它层次,称为共享层。
    分层也可以认为是抽象的一种方式,将系统抽象分解成若干层次化的模块。
    image
    今天的互联网系统可以认为是现代文明的一个层次,其上是基于互联网的现代商业,其下是现代电子工业基础设施。

四、分治思维

  1. 分而治之(divide and combine或者split and merge)也是应对和管理复杂性的一般性方法,下图展示一个分治的思维流程:
  2. 分治:分解和合并
    分解: 对于一个无法一次解决的大问题,我们会先把大问题分解成若干个子问题,如果子问题还无法直接解决,则继续分解成子子问题,直到可以直接解决的程度,这个是分解(divide)的过程;
    合并: 将子子问题的解组合拼装成子问题的解,再将子问题的解组合拼装成原问题的解,这个是组合(combine)的过程。

【面试题】 给你一台8G内存/500G磁盘空间的普通电脑,如何对一个100G的大文件进行排序?假定文件中都是字符串记录,一行约100个字符。
【思路】 100G的大文件肯定无法一次加载到内存直接排序,所以需要先切分成若干小问题来解决;
【拆解1】 8G内存的计算机一次大概能排多大的数据量,可以在有限的时间内排完呢? 100G的大文件要怎么切法,切成多少份比较合适?【 考察候选人的时间空间复杂度估算能力】
【解题】 8G内存,排除操作系统消耗,Java排序程序JVM可用2~4G内存,基于经验值,一次排1G左右的数据应该没有问题; 所以100G的文件需要先切分成100份,每份1G,这样每个子文件可以直接加载到内存进行排序。另外, 对于1G数据量的字符串排序,采用Java里头提供的快速排序算法是比较合适的。
【分解2】现在硬盘上有100个已经排好序的文件,但是我们最终需要的是一个排好序的文件,下面该怎么做? 这个时候我们需要把已经解决的子问题组合起来,合并成我们需要的最终结果文件。【 考察候选人对外排序和归并排序算法的掌握程度】
【解题】 将100个排好序的文件进行两两归并排序,这样不断重复,我们就会得到50个排好序的文件,每个大小是2G。然后再两两归并,不断重复,直到最后两个文件归并成目标文件,这个文件就是100G并且是排好序的。( 因为是外排序+归并排序,每次只需要读取当前索引指向的文件记录到内存,进行比较,小的那个输出到目标文件,内存占用极少。 另外,上面的算法是两路归并,也可以采用多路归并,甚至是采用堆排序进行优化)

【考点】 分治思想; 算法:快排,外排序,归并排序,堆排序; 计算的时间空间复杂度估算,计算机的内外存特性和组织,文件操作;
3. 分治: 递归
A. 掌握递归技术的开发人员,相当于掌握了一种强大的编程武器,可以解决一些一般开发人员无法解决的问题。
B. 大自然中递归结构比比皆是, 大自然通过递归给我们人类何种启示?
image

五、演化思维

  1. 架构是设计出来的?还是演化出来的?基于多年的架构经验来说,架构既是设计出来的,同时也是演化出来的,对于互联网系统,基本上可以说是三分设计,七分演化,而且是在设计中演化,在演化中设计,一个不断迭代的过程
  2. 在互联网软件系统的整个生命周期过程中,前期的设计和开发大致只占三分,在后面的七分时间里,架构师需要根据用户的反馈对架构进行不断的调整。
  3. 架构师除了要利用自身的架构设计能力,同时也要学会借助用户反馈和进化的力量,推动架构的持续演进,这个就是演化式架构思维。
  4. 优秀的架构师深知,能够不断应对环境变化的系统,才是有生命力的系统,架构的好坏,很大部分取决于它应对变化的灵活性。所以具有演化式思维的架构师,能够在一开始设计时就考虑到后续架构的演化特性,并且将灵活应对变化的能力作为架构设计的主要考量。
  5. 社区正在兴起一种新的架构方法学~演化式架构,微服务架构就是一种典型的演化式架构,它能够快速响应市场用户需求的变化,而单体架构就缺乏这种灵活性。
  6. 马丁·福乐曾经在其博客上给出过一张微服务架构的演化路线图,可以用来解释设计式思维和演化式思维的差异,如下图所示:
    image
    【设计式思维】----上行路线
    【问题】上面的路线是一开始就直奔微服务架构,其实背后体现的是设计式架构的思维 ,认为架构师可以完全设计整个系统和它的演化方向。
    【风险分析】马丁认为这种做法风险非常高,一个是成本高昂,另外一个是刚开始架构师对业务域理解不深,无法清晰划分领域边界,开发出来的系统很可能无法满足用户需求。

      【演化式思维】----下行路线
      上面的路线是从单体架构开始,随着架构师对业务域理解的不断深入,也随着业务和团队规模的不断扩大,渐进式地把单块架构拆分成微服务架构的思路,这就是演化式架构的思维。
      目前大多数大型互联网公司得系统架构走得都是演化式架构的路线。类似下面的建筑的演化史,在每个阶段,你可以看到设计的影子:
image

六、如何培养架构思维【总结】

  1. 工作中大量高质量项目的实战锻炼
  2. 平时的学习、思考和提炼总结
  3. 基本的架构设计思维, 可以从数据结构和算法中可以找到影子
  4. 对于演化设计思维, 更多在实际工作中通过实战锻炼和培养

  1. 一个架构师的成长高度和他大学期间的思维习惯的养成关系密切
  2. 世界一流的互联网公司,例如谷歌等,招聘工程师新人时,对数据结构和算法的要求可以用苛刻来形容

  1. 掌握了抽象、分层、分治和演化这四种基本的武器,你可以设计小到一个类,一个模块,一个子系统,或者一个中型的系统,也可以大到一个公司的基础平台架构,微服务架构,技术体系架构,甚至是组织架构,业务架构等等;
  2. 架构设计不是静态的,而是动态演化的。只有能够不断应对环境变化的系统,才是有生命力的系统。 在设计的同时,借助反馈和进化的力量推动架构的持续演进。
  3. 架构师在关注技术,开发应用的同时,需要定期梳理自己的架构设计思维,积累时间长了,你看待世界事物的方式会发生根本性变化,你会发现我们生活其中的世界,其实也是在抽象、分层、分治和演化的基础上构建起来的。
  4. 对抽象、分层、分治和演化掌握的深度和灵活应用的水平,直接决定架构师所能解决问题域的复杂性和规模大小,是区分普通应用型架构师和平台型/系统型架构师的一个分水岭。

以上是关于架构思维:抽象分层分治演化的主要内容,如果未能解决你的问题,请参考以下文章

成为架构师课程系列架构设计中的核心思维方法

第四章 软件架构演化

第四章 软件架构演化

架构思维-《API网关概览篇》

读书笔记-01大型网站架构演化-思维导图

译 ELK日志中心分布式架构的逐步演化