项目中工策略模式的实际使用

项目中工厂模式的简单使用

1.前提背景:
  • 项目中的财务开票管理模块原本对接了开票公司A,可以接口自动对接开具增值税普通电子发票,但是增值税纸质专用发票需要财务线下进行开具然后上传到自己的erp系统中。现在需要对接开票公司B,专门用来开具增值税纸质专用发票的开具。发现接口功能大体相似,都是需要开具和查询两个功能,所以可以使用工厂模式,创建对应的实现类调用对应的方法进行开票。
2.简单思路
    1. 创建一个工厂类(OrderTicketFactory),该工厂通过SpringUtils.getBean()方法返回指定的接口(ITicketService)
    2. 接口(ITicketService)中包含共有的方法,比如申请开票(callCreateApi)和查询开票接口的接口(callQueryApi)
    3. 开票公司A和开票公司B调用接口的具体实现类实现接口(ITicketService)并重写接口的方法。
    4. 在需要调用的地方,注入或者新建工厂类,通过参数获取到对应的接口实现类进行使用
3.代码:
  • OrderTicketFactory

    • /**
       * 发票实现类工厂
       */
      @Service
      public class OrderTicketFactory {
      
          private static final String SUFFIX = "orderTicket";
          /**
           * 根据传入的业务类型获取对应的服务类
           * beanName 定义为 orderTicket + type
           */
          public ITicketService getOrderService(String type) {
      
              return SpringUtils.getBean(SUFFIX + getTicketFactoryType(type));
          }
      
          private String getTicketFactoryType(String requestType) {
              if (TicketQueryTypeEnum.B.getValue().equals(requestType)) {
                  return "Etc";
              } else {
                  return "Invoice";
              }
          }
      }
      
  • ITicketService

    • /**
       * @author 服务申请接口
       */
      public interface ITicketService {
      
      	/**
      	 * 确认开票
      	 * @param ticket
      	 * @param mcEleInvoice
      	 * @return
      	 */
      	R callCreateApi(McOrderTicket ticket, McEleInvoice mcEleInvoice);
      
      
      	/**
      	 * 查询发票信息
      	 *
      	 * @param mcEleInvoice
      	 * @return
      	 */
      	R callQueryApi(McEleInvoice mcEleInvoice);
      
      }
      
  • 开票公司B具体实现类

    • /**
       * 开票公司B发票实类
       */
      @Service("orderTicketEtc")
      @Slf4j
      public class EasyTicketCloudServiceImpl implements ITicketService {
      	
      	/**
      	 * 开票 纸质专票
      	 * @param ticket
      	 * @param mcEleInvoice
      	 * @return
      	 */
      	@Override
      	public R callCreateApi(McOrderTicket ticket, McEleInvoice mcEleInvoice) { 
      		try {
      			// // 具体的组装请求,略
      		} catch (HttpException e) {
      			log.error("调用开票接口报错!",e);
      			return R.error("调用开票接口报错!");
      		}
      	}
          
      	/**
      	 * 查询 销项发票池
      	 * @param mcEleInvoice
      	 * @return
      	 */
      	@Override
      	public R callQueryApi(McEleInvoice mcEleInvoice) {
      		try {
      			// 具体的组装请求,略
      		} catch (HttpException e) {
      			log.error("调用查询接口报错!",e);
      			return R.error("调用查询接口报错!");
      		}
      
      	}
      }
      
  • 开票公司A具体实现类

    • /**
       * 开票公司A发票实类
       */
      @Service("orderTicketInvoice")
      @Slf4j
      public class EasyTicketCloudServiceImpl implements ITicketService {
      	
      	/**
      	 * 开票 电子普票
      	 * @param ticket
      	 * @param mcEleInvoice
      	 * @return
      	 */
      	@Override
      	public R callCreateApi(McOrderTicket ticket, McEleInvoice mcEleInvoice) { 
      		try {
      			// // 具体的组装请求,略
      		} catch (HttpException e) {
      			log.error("调用开票接口报错!",e);
      			return R.error("调用开票接口报错!");
      		}
      	}
          
      	/**
      	 * 查询 销项发票池
      	 * @param mcEleInvoice
      	 * @return
      	 */
      	@Override
      	public R callQueryApi(McEleInvoice mcEleInvoice) {
      		try {
      			// 具体的组装请求,略
      		} catch (HttpException e) {
      			log.error("调用查询接口报错!",e);
      			return R.error("调用查询接口报错!");
      		}
      
      	}
      }
      
  • 具体的使用:

    • 	// 我这里直接使用@Autowired注入了,其实也可以直接把工厂类的方法变成静态的方法,就可以直接通过类名调用,类似工具类的使用
      	@Autowired
      	private OrderTicketFactory orderTicketFactory;
      	
      
      	// 在具体需要使用的方法里面
      	// type 为请求类型,使用这个type判断是需要开票公司A还是开票公司B
      	String type = "1"
      	ITicketService ticketService = orderTicketFactory.getOrderService(type);
      	R r = ticketService.callQueryApi(invoice);
      	// 得到对应的开票结果,进行解析使用
      
      

简单来说就是如此,当同一个方法有多种不同的处理的时候,使用工厂模式。比如发短信有对接多个供应商进行发送、或者同一项业务对应不同的国家有不同的处理,都可以使用简单的工厂模式使代码后期更好维护。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
代码如下,模板类字段是动态的,怎么改造代码: setResponseHeader("项目工单统计-工单统计工单位置", response); //表头 List<List<String>> header = new ArrayList<>(); header.add(Lists.newArrayList("位置", "一级位置")); header.add(Lists.newArrayList("位置", "二级位置")); header.add(Lists.newArrayList("位置", "三级位置")); header.add(Lists.newArrayList("工单总数", "工单总数")); header.add(Lists.newArrayList("进行中工单数", "进行中工单数")); header.add(Lists.newArrayList("已挂起工单数", "已挂起工单数")); header.add(Lists.newArrayList("挂单率", "挂单率")); header.add(Lists.newArrayList("已完成工单数", "已完成工单数")); header.add(Lists.newArrayList("完成率", "完成率")); //组装导出dto List<OrderLocationAnalysisDTO> list = this.getOrderLocationAnalysisDTOList(query); List<Integer> workOrderTypeList = new ArrayList<>(); //公区报单 workOrderTypeList.add(11); WriteTable head = EasyExcel.writerTable(0).needHead(Boolean.TRUE).build(); ExcelWriter writer = EasyExcel.write(response.getOutputStream()).build(); WriteTable data = EasyExcel.writerTable(1).needHead(Boolean.TRUE).head(header).build(); WriteSheet sheet = EasyExcel.writerSheet(0).needHead(Boolean.FALSE).sheetName("工单统计工单位置导出").build(); writer.write(concatHead("工单统计工单位置导出",query.getTimeRange().getStartTime(),workOrderTypeList), sheet, head); writer.write(list,sheet,data); writer.finish();
05-31

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值