细数软件架构中的解耦

解耦的对立面是耦合,耦合是指阻碍变化的依赖;解耦是要在依赖的基础上,做到应对可能的变化 。
架构的定义架构是软件方法学的范畴,它解决的是软件组织的问题,不解决软件算法的问题 。两者的区别可用下图的积木做个类比:
算法就像一个个的积木块,比如绿色的圆柱,蓝色的三角,红色的方块等 。而架构则是把各种积木块,组装成一个城堡,一辆小火车 。为搭建这个城堡或小火车,架构师脑子里得有张图纸,图纸里既要定义需要哪些形形色色的积木块,又要考虑如何将它们组装起来 。这工作很像建筑师,英文也的确叫 architect 。
这样类比,很容易让不太理解技术的企业家们陷入误区,会觉得架构师要比算法工程师更厉害?其实不然,这是两个细分领域的才能 。不知道您注意到小火车车头上的烟囱没?它是一个像鸡腿菇一样的弧线造型,浇灌出这种造型的模子,要比三角形和方块形要难很多,它需要更深奥的几何学的支撑,这可以形象的看做是算法工程师解决的问题 。
架构的意义架构解决软件组织的问题,它能给企业创造什么价值?换句话说,好的软件组织,跟差的软件组织,从商业价值创造的角度,有什么不同?笔者以为架构的价值体现在可用性和敏捷性两个角度,但今天要讲的是敏捷性 。敏捷性指的是快速、低成本、高质量地应对扩张市场的差异化需求 。企业在初创期积累了不少软件资产,这些资产在当初的市场环境下,已被论证取得了市场业绩 。但是伴随着企业扩张,市场会更加精细化、场景化,这些都会给我们的软件提出新的需求,企业需要借助前些年在这个领域积累的先发优势,一方面快速占领细分的市场;另一方面复用曾经积累的资产,发挥资产的规模经济效应 。
比如京东电商,从高价值、标准化的 3C 数码起家,建立起自营电商模式;紧接着开始扩品,做低价值、但高频次、依然标准化的日用百货圈用户粘性;再做相对非标的服装发展女性用户和生态模式等,直指行业竞争的关键区;除了扩品还伴随着场景扩张,诸如 2B 企业业务、下沉市场拼购业务、泰国印尼国际业务等 。供给角度的品类扩张,需求角度的场景扩张,构成了京东矩阵式垂直业务线 。它们正是复用了零售中台的软件基础设施,才在一定程度上做到了快速扩张 。
架构的灵魂既然软件组织的价值如此重要,那么好的软件组织的标准是什么呢?又该如何做到呢?好坏的标准在解耦 。解耦的对立面是耦合,耦合是指阻碍变化的依赖;解耦是要在依赖的基础上,做到应对可能的变化 。依赖是必不可少的,依赖的本质是分工,正如亚当斯密的《国富论》论述的那样,分工有助于专业化、有助于提高效率 。太抽象了!说了这么多,没讲清楚解耦是什么 。的确,笔者也认为这样的解释只能让已经理解了的人再表示一次赞同,无法让原本不理解的人变得理解,这样毫无意义!我该如何诠释?事实上,很多真理是建立在归纳法基础上的 。归纳法的好处是见得多了自然就会(归纳似乎是人脑的一种本能),比如诗词,只要熟读唐诗三百首,不会吟诗也会吟 。不信你看,先来一篇叫“大漠孤烟直”的,没啥概念;再读一篇叫“空山新雨后”的,有点感觉了;最后“小桥流水人家”你自己就会了 。如何写出点有意境的诗,你张口就来“床前明月光”,还不是自己写的?如果你去到草原晚上触景生情,即兴来上一句“明月篝火烤肥羊”,就能媲美“日照香炉生紫烟”了 。所以笔者觉得,最好的方式就是细数那些软件架构中的解耦,让读者从铺陈式的实例中,自己找感觉 。
笔者分 3 类 6 组(每类分进程内的应用层和进程间的架构层)给大家举例:

细数软件架构中的解耦

文章插图
 
外加中间的 Naming 解析与 Proxy 代理融合的 CNAME 别名,总共 7 个案例 。
中间层映射
中间层映射的设计理念是当 A 对 B 有依赖时,A 不要直接依赖 B,而是抽象一个中间层,让 A 依赖中间层,再由中间层映射到 B,从而当 B 变成 C 时,不用修改 A,只用调整中间层的映射关系 。中间层映射,在应用层表现为面向接口动态绑定,在架构层表现为 Naming 解析动态绑定 。
应用层 - 面向接口动态绑定
面向接口编程的核心思想是“先想清楚做什么,再想让谁来做” 。什么叫想清楚了做什么?就是用接口的形式,描述输入什么,输出什么;但接口更多描述的是语法层面,语义层面的刻画还需配合单元测试及其断言(技术上叫 Test Driven),还有文档 。这跟企业家们常读的《高效能人士的 7 个习惯》里面讲的“以终为始”,思想上如出一辙 。让谁来做?就涉及到运行时动态绑定 。比如下图:


推荐阅读