架构思维第三篇
Posted hanruikai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了架构思维第三篇相关的知识,希望对你有一定的参考价值。
技术架构-高扩展
可扩展的意思是在面对变化时,用最少的代价去实现,平时我们听得最多的是面向抽象(接口)编程,如果只是把这里的抽象理解成接口,那么就有些狭隘了,抽象是通式通法,而接口只是其中一个,所以在谈可扩展实现之前一定要讲清楚可扩展的本质是什么,连本质都不知道,怎么提出系统性解决方案。
扩展本质
扩展的本质就是占位符,凡是可以表达变化的就是占位符。
应对扩展的方法
先给出应对可扩展的方法:规范、识别、注册、使用,这 4 点都是从上面可推导出来的,下面一一进行详细说明。
-
规范:规范是从占位符推导出来的,既然是标志有变化,一定要遵循一定的规范表达,否则别人是不知道的,如接口,就是很直接地表达这里是有变化的,具体的实现还不知道;变量天然地表达这里是变化的数据。
-
识别:有了规范定义之后,接下来就是识别,之前为什么可扩展一直对我们来讲很虚,那是因为规范和识别都是系统帮我们做的,我们只是知道而没有真正实践。规范是定义,识别是找出有哪些实现了规范。
-
注册:识别出来之后,就要把信息存储起来,可以存储在本地,也可以存储在远程,如果存储在远程就是一个注册的过程,这里的注册就是存储的意思。简单理解就是识别出来之后要集中管理。
-
使用:使用就很简单,找到具体实现并执行逻辑处理。
上面四个单词看起来简单,除了使用是终极目标外,其它三个都是抽象的表达,比如规范如何定义、怎么识别、如何注册?通过上面的表述可以看到具体要怎么实践,这里再总结下:
-
规范如何去定义:凡是可以表达变化的就能用它来定义,常见的有配置项、变量、接口、注解等;
-
怎么去识别:这个要具体去看如何定义规范,如配置项的变化有一个监听变化;注解是要扫描类来识别 annotation;
-
如何去注册:如果系统的交互只是一个,那么存储在本地就行,如果系统的交互是多个,那么要注册到一个注册中心上去。
结论:应对可扩展的方法:规范、识别、注册、使用。
扩展经典案例
此处使用一个经典案例来说明可扩展性,并从其原理上印证上述方法。
在 Java 中,SPI 对于大部分人来讲并不陌生,最典型的加载数据库驱动就是通过 SPI 来实现的。如果你看了 SPI 的原理,再去看上面写的,会感觉两个思路很相似。
SPI 有它的规范,要到指定目录下加载对应文件;找到文件后进行解析、识别并加载;最后就是使用。整个流程能印证上面所提到的:规范、识别、注册、使用。所以,方法的提出有一个点就是从具体案例中进行抽象,提炼共性的东西,再去推演其它案例看能不能也满足。
可扩展实例
此处以优惠券业务平台为例讲解可扩展性系统设计与实现,在上一篇文章中已经讲了优惠券系统是一个平台型的业务系统,要做到业务与业务的隔离、业务与平台的隔离。
识别变化
经过整体分析之后,已经确定大业务流程:建券、发券、用券、退券,以及对应的子流程,接下来就是要分析出哪些内容会变化。
比较明显的变化就是领券、用券门槛的变化,因为不同业务线有不同的限制条件,有的要限制不同人群,有的要限制领取次数…已经认别了变化接下来就是要处理这些变化。
找扩展点就是找系统经常变化的地方。
处理变化的常用手段
野蛮代码
一个最简单的处理,就是在代码中写 if else,它的特点是简单直接上线,不足的点长期下去,系统会变得很难维护、可扩展性较差。
面向接口
对上面野蛮方式的一个常见处理就是面向接口设计,抽象出一个限制条件检查的接口,不同的业务线有对应的实现,通过配置指定业务线下所有的实现,将这些实现放到一个映射中,在程序执行过程中,通过业务线就可以执行所有的接口实现类并依次执行。
List<Rule> ruleList = RuleFacotry.getByProductId(prodcutId);
这种方法比第一种明显要好,体现了一定的可扩展性,新加一个规则限制,重新实现接口就行,然后在配置项中加上这个新的实现,代码的改动量也还好。它有一个明显的问题就是每次新加一个实现就要发布上线,有没有办法不发布上线就能满足目的呢?有,就是下面提到的一类可扩展性设计的方法。
一类可扩展性设计方法
再来明确一下目标:系统具备可扩展性和不发布系统就能实现新增功能。
还是使用上面说的方法:规范、认别、注册、使用,下面结合这个具体的案例来说明。
-
规范:这里是用接口来作为规范描述限制条件,包含入参和出参,这里有一个开放平台,实现了一个接口后就可以提交代码。
-
识别:在建优惠券时,会加载业务线有哪些业务规则实现,在领取、使用时可以进行配置选择,此时只是插入一个变量标识使用某个限制条件(如限人群,这个实现的逻辑可能会变化,通过变量名来标识变化)。
-
注册:系统在执行的过程中,发现有限制条件的变量名,拿这个变量名从开放平台中拉取具体的实现存储在本地(有一个缓存时间,具体的过期时间依业务考虑,我们取的是 30 分钟)。
-
执行:拿到具体的实现后,依次执行。
再整理下流程步骤,让大家更进一步掌握该设计方法:
-
在开放平台提交限制条件接口的实现代码,有限制人群的实现、限制领取券次数…
-
在开放平台提交之后,会入库存储,数据库里会存储一个业务线对应的多个限制实现。
-
创建优惠券时,会加载业务下的限制规则,通过配置选择具体要使用到的限制规则(相同业务线下的不同优惠券可以有不同的规则限制),配置选择后,会在规范字段中存储规则实现的 id(规则实现可能会变化,会有多次提交),所以这里存储的是 id,在执行的时候可以拿到这个 id。
-
在领券、用券时,会检查规则限制有哪些,通过 id 列表从远程开放平台拉取具体实现,把 java 代码拉下来之后就可以编译,并存储到本地或者集群缓存中。
-
最后就是执行具体的实现逻辑。
原文地址:
https://www.infoq.cn/article/1w2MJZzx-0dm9j9VYSam
以上是关于架构思维第三篇的主要内容,如果未能解决你的问题,请参考以下文章