如何设计一种网关类型的服务端架构

系统设计时经常会遇到类似的需求:设计一个系统,为公司内(外)的其它系统提供XX服务(登录、支付等,为了表述方便,下面以支付为例),这个系统需要对接其它若干支付系统,如:对接支付宝,对接微信支付,对接网银等。此处,我们把要设计的系统叫做XX网关系统。

一般设计方案

最直接的方法是,每对接一个新的支付,创建一套对应代码,从service、manager到dao完全写一套,然后把新支付需要的参数直接暴露给调用方。
  或者是对系统调用方提供一个请求参数的聚合体,同时增加一个支付类型参数,每新增加一种支付,就把请求参数放到这个聚合体中。系统根据请求类型不同来筛选请求参数与处理方法。

如何设计一种网关类型的服务端架构_第1张图片
一般设计

存在的问题

上面的方案其实只是一种简单的封装,它存在以下问题:
1、每当新增加一种支付,系统调用方都需要增加对应的额外的参数与对应的代码,而且每个系统调用方都需要去实现一遍
2、在系统中存在大量冗余代码,涉及到变更,很可能需求修改多处
总的来说就是难以维护,维护工作量大

我们希望的是

一种扩展灵活,易于维护的系统,对于新的支付的接入,不需要开发大量的重复代码,系统调用方也不需要做大量的改动,只需要少量改动即可(或者不改动)。

另一种设计

下面我来说一说另一种方案以及其实现步骤,大家仔细体会一下区别。
对外只提供一个调用接口,通过参数类型来区分不同的支付处理类,提取出支付必须的通用参数创建请求参数,并增加支付类型参数,提取公共实现类,设计模板方案,实现具体的支付类。

步骤

下面的代码,只是为了对步骤进行说明,没有参数校验与异常检测,不能直接用于线上系统。

一、设计接口层

接口的目的之一就是定义外部通信的协议。
1、提供模块调用的服务,如,pay
2、提取支付的必须(公共)参数作为请求参数
3、提供支付类型参数,用于区分交易类型(此类型可以作为查询参数返回到客户端侧,这样的话,调用方就完全不用关心新增类型的事情了,读者请自行思考)

如何设计一种网关类型的服务端架构_第2张图片
接口设计
如何设计一种网关类型的服务端架构_第3张图片
支付请求参数

二、提取抽象基类,完成公共代码

1、完成公共代码开发,生成模板方法
类似如下:
abstract doSomethingA(); 抽象方法,需要子类实现
common method(); 通用的代码逻辑,比如更新DB
abstract doSomethingB(); 抽象方法,需要子类实现

公共接口定义,如保存支付记录,发起支付请求,为service层提供调用,其中getPayTpe是为工厂提供调用的。


如何设计一种网关类型的服务端架构_第4张图片
公共支付接口定义

提取抽象方法,编写公共代码。注意此处泛型的使用。


如何设计一种网关类型的服务端架构_第5张图片
公共支付接口实现类

支付工厂类实现,通过getBeansOfType来加载所有实现了BasePayManager的类,放到内存中。


如何设计一种网关类型的服务端架构_第6张图片
支付工厂类实现

三、编写具体子类实现

定义具体支付的接口,用于编写支付类特有方法。支付接口特有的参数在具体子类中隐藏掉,不对外暴露。


具体支付类接口定义

实现具体的支付功能


如何设计一种网关类型的服务端架构_第7张图片
具体支付类实现

四、编写PayService实现类

从工厂类获取具体的支付处理类。调用BasePayManager的doPay方法。


如何设计一种网关类型的服务端架构_第8张图片
入口实现方法

类图:

如何设计一种网关类型的服务端架构_第9张图片
类图

总结

此处我们使用了开闭原则,面向接口编程,模板方法等技巧,后续再增加新的支付,只需要编写具体的实现类即可(XXManager),不会因为新的加入而影响原有功能。
  最后说一点感悟,作为一个开发人员,我们要主动的去提高自己的竞争力,如果已经写了3年以上代码了,还只停留在service,manager,dao层面上,这是很危险的,慢慢的就会被淘汰。因为这些即使是一个1年工作经验的人,只要做的足够多,那么他也可以熟练掌握。而如果我们还只停留在这个层面上,没有基类与进步,那用不了多久就会失去竞争力。

你可能感兴趣的:(如何设计一种网关类型的服务端架构)