作为开发人员,你对复用这个概念肯定不生疏。在开发过程中,咱们把零碎中通用的代码逻辑抽取进去,变成公共办法或公共类,而后在多个中央调用,这就是最简略的技术上的复用。

但一开始,咱们不会过多地思考复用,当一个新我的项目过去,咱们会抉择最间接的形式来实现,后果往往是欲速而不达,比如说:

  • 好不容易搞定了一个我的项目,接着又有新的相似我的项目过去,咱们又要从头再来;
  • 我的项目的代码是定制的,我的项目完结后,系统维护的噩梦刚刚开始。

如果我的项目不足积淀,每个我的项目都是全新的开始,呈现这些状况,一点都不意外。而要想解决这个问题,咱们一开始就要思考零碎的复用性。

复用,它能够让咱们站在伟人的肩膀上,基于现有的成绩,疾速落地一个新零碎。

那么,咱们在做架构设计时,如何实现零碎的高可复用呢?

复用的分类

复用有多种形式,它能够分为技术复用和业务复用两大类。

  • 技术复用 包含代码复用和技术组件复用;
  • 业务复用 包含业务实体复用、业务流程复用和产品复用。

从复用的水平来看,从高到低,咱们能够顺次划分为产品复用>业务流程复用>业务实体复用>组件复用>代码复用。

接下来,我就依照复用度从低到高,对这些复用形式进行一一剖析,帮忙你更好地了解架构的可复用性。

技术复用

首先是 代码级复用,这部分应该是你最相熟的了。这里包含你本人打包的类库,第三方提供的SDK,还有各种算法封装等。咱们的代码能够间接调用它们,物理上也和咱们的利用打包在一起,运行在同一个过程里。代码级复用是最低档次的复用,你能够把它当作你本人源代码的一部分。

再往上,是 技术组件复用。这些组件有咱们本人封装的,更多的是大量开源的中间件,比方Redis、MQ、Dubbo等;组件也包含各种开发框架,比方Spring Cloud。这些根底组件技术复杂度很高,它们的存在,极大地简化了咱们的开发工作。

值得注意的是,代码级复用和技术组件复用都属于工具层面,它们的益处是在很多中央都能够用,但和业务场景隔得有点远,不间接对应业务性能,因而复用的价值绝对比拟低。

业务复用

咱们晓得,零碎最终是为业务而服务的,如果可能实现间接的业务复用,那零碎开发的效率就更高。比如说,微服务强调单个业务实体的封装和复用,而中台进一步实现了企业级业务能力的复用。

所以接下来,咱们就从比较简单的业务实体复用开始说起。

业务实体复用针对细分的业务畛域,比方订单、商品、用户等畛域。它对各个业务畛域的数据和业务规定进行封装,将它变成下层利用零碎能够间接应用的业务组件。

业务流程的复用针对的是业务场景,它能够把多个业务实体串起来,实现一个端到端的工作。比如说,下单流程须要拜访会员、商品、订单、库存等多个业务,如果咱们把这些调用逻辑封装为一个下单流程服务,那下单页面就能够调用这个流程服务来实现下单,而不须要去深刻理解下单的具体过程。相比单个的业务实体复用,业务流程的复用水平更高,业务价值也更大。

最高档次的复用是对整个零碎的复用,比如说一个SaaS零碎(Software-as-a-Service),它在外部做了各种通用化设计,容许咱们通过各种参数配置,失去咱们想要的性能;或者说一个PaaS(Platform-as-a-Service)平台,它会提供可编程的插件化反对,容许咱们“嵌入”内部代码,实现想要的性能。

这种产品级的复用,它的复用水平无疑是最高的。这样的零碎,在落地的时候,它无需外围的开发团队进行开发,只由外围的施行团队负责就能够了,这样,一个我的项目的上线就能简化为一次疾速的施行,岂但上线周期短,零碎也更稳固。

当然,实现这样的复用,难度也是很大的,你既要对所在行业的业务有很全面的了解,又要有很强的形象设计能力。这类零碎中,比拟典型的有Salesforce的CRM零碎和SAP的ERP零碎。

咱们先对复用做个总结。 从技术复用到业务复用,越往上,复用水平越高,复用产生的价值也越大,但实现起来也越简单,它能复用的场景就越无限。 在理论工作中,技术层面上的复用绝对比较简单,咱们对这部分的认知也最多,而且因为开源的遍及,当初有丰盛的中间件让咱们抉择,咱们能够基于它们,逐渐构建适宜本人的技术体系。

但如果咱们能进一步打造业务中间件,并在这个根底上,造成业务平台,这样,咱们就能实现更高的业务级复用,能够更高效地支持系统的疾速落地。

而在实现业务组件化和平台化的过程中,首要的问题就是根底服务边界的划分。边界划分决定了服务的粒度和职责,在理论工作中,也是十分困扰咱们和有争议的中央。

接下来,我就针对根底服务边界的划分,分享一些实用的准则和做法。

服务边界划分准则

服务边界划分要解决“我是谁”的问题,它实现了服务和周边环境的清晰切割。

咱们都晓得,服务蕴含了业务数据和业务规定,并提供接口给内部拜访,其中,接口是服务的对外视图,它封装了服务的业务数据和规定。

所以从边界划分的角度来看,咱们就是要确定哪些数据属于这个服务,哪些接口性能由这个服务提供。这里,我总结了3个根底服务边界划分的准则,供你设计时做参考。

1服务的完整性准则

在划分服务的边界时,须要确保服务外部数据的完整性。

举个例子,一个商品服务的数据模型,不仅要有商品根本信息,比方商品名称、价格、分类、图片、形容等;还须要蕴含商品的扩大信息,如商品的各种属性、商品标签等;最初还要蕴含各种简单商品类型的定义,比方组合商品、套餐商品、多规格商品等。

另外,你还要保障服务性能的完整性。对于服务使用者来说,他们是以业务的角度看服务,而不是纯正的数据角度。比方一个套餐商品,在服务外部,它是多个单品的简单组合,但从服务调用者的角度来看,它就是一个商品。

那当初问题来了,对于套餐的价格,商品服务是给出一个最终价格呢?还是给出各个单品的价格,而后让调用方本人算最终价格呢?咱们晓得,套餐的价格不是各个单品价格累加的后果,它蕴含了肯定的优惠,如果它的价格由服务调用方来算,这会导致商品的局部业务规定游离于服务里面,毁坏了商品服务的性能完整性。

在实践中,有些服务只是存储根底数据,而后提供简略的增删改查性能,这样一来,服务只是一个简略的DAO,变成了数据拜访通道。这样的服务,它的价值就很无限,也容易被服务调用方质疑。因而,咱们要尽可能在服务外部封装残缺的业务规定,对外提供残缺的业务语义,最大水平地简化服务的应用。

所以,当你在划分服务边界时,要保障服务数据残缺、性能全面,这样能力撑持一个残缺的业务畛域。

2服务的一致性准则

也就是说,服务的数据和职责要统一,谁领有信息,谁就负责提供相应的性能。

服务外部的业务逻辑要尽量依赖外部数据,而不是接口输出的数据,否则会造成数据和业务规定的脱节(一个在里面,一个在外面),如果服务对外部的依赖性很强,就无奈提供稳固的能力了。

很多时候,咱们对一个性能到底划分到哪个服务,有很大的争议。这时,咱们能够联合这个性能所依赖的数据来判断,如果性能所须要的大部分数据都存储在A服务里,那当然由A服务来提供接口比拟适合,这样接口输出的数据比拟少,岂但简化了服务对外部的依赖,同时也升高了接口调用的老本。

给你举个例子,在订单小票上,咱们常常能看到一些优惠信息,比如说商品原价是多少,其中因为满减优惠了多少,因为商品特价减免了多少。这个优惠计算的后果是订单的一部分,毫无疑问,它须要保留在订单服务里。

但这个订单的优惠计算过程,却不是由订单服务来负责,而是由独立的促销服务负责的。因为优惠计算所须要的优惠规定是在促销服务里定义的,促销服务能够在外部拿到所有的优惠规定,而后实现整个优惠计算。

否则,如果是由订单服务负责优惠计算,订单服务的调用者就须要在接口中提供残缺的促销规定,岂但调用老本高,而且内部促销规定的扭转会影响订单服务的外部实现。

所以在这里,促销服务负责促销规定的保护,以及对应的优惠计算性能;订单服务负责优惠后果数据落地,以及后续的查问性能。这样,每个服务存储的数据和对外提供的性能是统一的。

3正交准则

既然是根底服务,它们就处于调用链的底层,服务之间不会有任何的调用关系,也就是说根底服务相互之间是正交的。比如说会员服务和商品服务,它们代表不同维度的根底业务域,彼此之间不会有调用关系。

正交还有另外一种状况:服务之间有数据的依赖关系,但没有接口的调用关系。

比如说,订单明细里蕴含商品ID信息,但订单服务外部不会调用商品服务来获取商品详情。如果页面须要展现订单的商品详情,针对这个具体的业务场景,咱们能够在下层的聚合服务里,通过聚合订单服务和商品服务来实现。

总结

可复用是架构设计的一个重要指标,本文对复用进行了梳理,包含复用有哪些模式,以及它们有哪些价值。 业务上的复用比纯正的技术复用有更高的价值,咱们要尽量往这个方向上靠。在实践中,落地根底服务是实现业务复用的无效形式,而根底服务边界的划分,它有迷信的成分,但更多的是一种艺术,这里我提供了几个实用的划分准则,大家能够在工作中结合实际状况,灵便地使用。

本文由mdnice多平台公布