性能文章>设计模式开发实践(外观、策略、代理)>

设计模式开发实践(外观、策略、代理)原创

1年前
498424

一、背景

  项目组接到新需求,在客运站站务系统窗口售票中,分销城际定制客运班线车票。传统汽车客运站班线客流逐年下滑,在网约车影响和政府政策主导下,传统汽车客运站开始寻求积极的业务转型,深度与城际出行、定制客运出行整合。
  既支持传统站务系统班线客运–分销至–定制客运售票,也支持定制客运车票–分销至–传统的客运站售票窗口。

1.1 业务分析

  • 知彼:分析定制客运分销接口调用逻辑;
  • 知我:站务系统窗口售票逻辑,考虑未来支持站务系统二次分销给第三方平台;

1.2 技术分析

  1. 策略模式:站务分销第三方售票,可能存在多个供应商,支持配置供应商模式;
  2. 外观模式:站务系统模块较多,内部调用分销接口,应该提供统一接口和方法;
  3. 代理模式:渠道http调用均是入参、请求、返参,相同功能交由代理类专人专做;

二、流程图

设计模式.png

2.1 单一职责原则

  客运站站务系统,一般部署在车站内网、集团内网环境。调用第三方的分销接口服务,应该满足单一职责原则,使其业务逻辑清晰,支持独立部署。在我们站务系统中,有一套独立的openapi接口程序,用于内外网数据交互和路由。本文对openapi接口程序不做赘述,以站务系统内部程序代码为主。

三、策略模式实现方式

3.1 策略模式核心

策略01.png

  多个ServiceBean可以实现相同的接口,根据ApplicationContext获取到容器中管理的Bean。每个实现类的Bean-name不相同,则实现不同策略。
  (ApplicationContext(应用上下文):继承BeanFactory接口,可以用来获取容器中的各种bean组件,注册监听事件,加载资源文件等功能。)

3.2 数据库表设计

策略11.png

  如图两个供应商渠道(团子城际出行、飞猪城际出现)(举例),可以配置不同的serviceBeanName。这里也可以不放在数据库表,放在config文件中也是一致的,目的只是策略适配器。

四、代理模式实现方式

4.1 数据库表配置

策略2.png
  按照上述供应商的配置,每个供应商有多个接口,而接口超时时间、接口限流次数等等的配置,我们将其放在数据库表中。
  思考:

  • 多数的外部调用方法,都是通过http方式请求;
  • http:http接口请求模式相同,均是url、组装入参、组装出差、请求;

4.2 转换器

public interface IConvert<R> {
    // 组装请求入参
    void buildReqParams(BaseRqDto reqdto,AdpChannel adpChannel) throws Exception;
    // 组装返回参数,用于处理返参
    void bildResParams()  throws Exception;
    // 请求
    void doRequest(IHttpManager httpManager,AdpChannel adpChannel) throws Exception;
    // 返回返参
    R getResult() throws Exception;
    // 组装url
    void buildReqUrl(MemoryData memoryData,AdpChannel adpChannel, String stationId) throws Exception;

}

4.3 代理类(http请求负责人)

19.png

4.4 伪代码

29.jpg

  规范大家对http的使用方式,使用代理类的action方法,完成整个从组装url、入参、http、返参组装的系列过程:

/**
 * @apiNote 获取线路班次
 * @author cll
 * @date  2023/3/6
 * */
private List<InterCityLineResDto> getLine(InterCityLineReqDto baseRqDto){
    IConvert<List<InterCityLineResDto>> convert = new InterCityLineCase<>();
    try{
        director.action(convert,baseRqDto);
        return convert.getResult();
    }catch (Exception e){
        e.printStackTrace();
    }
    return new ArrayList<>();
}

五、总结

  本次开发过程中使用设计模式主要三方面的目的:

  • 做好适配,方便后续同类业务需求开发(能加快后续开发进度),提效;
  • 做好定义,约束调用方式,让组内同事都按照一定规范来开发,规范代码;
  • 加强思考,锻炼抽象能力;
点赞收藏
站务精英

特长

请先登录,查看2条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

随机一门技术分享之Netty

随机一门技术分享之Netty

MappedByteBuffer VS FileChannel:从内核层面对比两者的性能差异

MappedByteBuffer VS FileChannel:从内核层面对比两者的性能差异

4
2