使用自定义注解,实现策略模式代替if else

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

需求:现有多种类型的回单,每种回单排版不同,使用数据取值也不同,所以需要根据回单类型,生成不同类型的回单。


一、什么是策略模式?

策略模式其实也是在解耦,把策略的定义、创建、使用这三个部分解耦开来,因为本身策略模式也是基于接口编程,这样其实可以简单的理解客户端调用使用接口进行编程,可以通过工厂方法创建对应的策略模式,进而完成对应的程序功能。(定义自己百度)

二、使用步骤

1.函数式接口

所谓的函数式接口,实际上就是接口里面只能有一个抽象方法的接口。(定义自己百度)

package com.hime.aoto.common.hdpdf;

import com.hime.aoto.project.entity.BillFlowGeneral;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;

/**
 * @author: lijx
 * @date: 2023/1/4 15:38
 * @description: 创建hdpdf内容的函数式接口
 */
@FunctionalInterface
public interface HdPdfTable {

    /**
     * 创建电子回单内容
     * 每个实现类取值设置样式区分开,解耦合,以便于后期修改回单样式,而不影响其他回单样式
     *
     * @param billFlowGeneralInfo 回单信息
     * @param cell  PdfPCell
     * @param pdfTable PdfPTable
     * @param printDate 打印时间
     */
    void careteTable(BillFlowGeneral billFlowGeneralInfo, PdfPCell cell, PdfPTable pdfTable, String printDate);
}

2.自定义注解

代码如下:

package com.hime.aoto.common.annotation;

import org.springframework.stereotype.Component;

import java.lang.annotation.*;
/**
 * @author: lijx
 * @date: 2022/10/10 9:53
 * @description: 回单类型注解
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface BillHandlerType {
    /**
     * 回单类型,与数据库中 bill_flow_general的bill_format字段保持一致
     *
     * @return
     */
    String source();
}

3.回单类型选择策略

代码中使用了Lambda表达式,仔细看应该不难懂

package com.hime.aoto.framework;

import com.hime.aoto.common.annotation.BillHandlerType;
import com.hime.aoto.common.hdpdf.HdPdfTable;
import com.hime.aoto.common.hdpdf.impl.BillAllRmfImpl;
import com.hime.aoto.common.hdpdf.impl.BillFeeRmfImpl;
import com.hime.aoto.project.entity.BillFlowGeneral;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: lijx
 * @date: 2023/1/4 16:19
 * @description: 回单类型生成策略
 */
@Component
public class HdPdfTableFactory {

    private Map<String, HdPdfTable> hdPdfTableMap;

    /**
     * 通过注解@BillHandlerType和Map实现策略模式
     *
     * @param hdPdfTableList
     */
    @Autowired
    public void setHdPdfTableMap(List<HdPdfTable> hdPdfTableList) {
        hdPdfTableMap = hdPdfTableList.stream().collect(
                Collectors.toMap(hdPdfTable -> AnnotationUtils.findAnnotation(hdPdfTable.getClass(), BillHandlerType.class).source(),
                        v -> v, (v1, v2) -> v1));
    }

    /**
     * 选择策略
     *
     * @param billType 回单类型
     * @param billFlowGeneralInfo
     * @param cell
     * @param pdfTable
     * @param printDate 打印时间
     */
    public void getHdPdfTable(String billType, BillFlowGeneral billFlowGeneralInfo, PdfPCell cell, PdfPTable pdfTable, String printDate){
        HdPdfTable hdPdfTable = hdPdfTableMap.get(billType);
        if(hdPdfTable != null){
            hdPdfTable.careteTable(billFlowGeneralInfo, cell, pdfTable, printDate);
        }
    }

}

4.接口实现类

根据不同的回单类型,编写不同的实现类,编码者不再关注怎么选择回单类型,只需编写不同类型的回单生成逻辑即可。 每个实现类只需要加上@BillHandlerType(source = “回单类型”)即可。

1)billall_rmf类型的回单

package com.hime.aoto.common.hdpdf.impl;

import com.hime.aoto.common.CreateModelNineType;
import com.hime.aoto.common.annotation.BillHandlerType;
import com.hime.aoto.common.hdpdf.HdPdfTable;
import com.hime.aoto.common.utils.DateUtils;
import com.hime.aoto.common.utils.PubUtil;
import com.hime.aoto.project.entity.BillFlowGeneral;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import org.springframework.stereotype.Service;

import static com.hime.aoto.common.CreateModelNineType.setCellMsgRowHead;

/**
 * @author: lijx
 * @date: 2023/1/4 15:44
 * @description: 最简类回单 billall_rmf
 */
@BillHandlerType(source = "billall_rmf")
public class BillAllRmfImpl implements HdPdfTable {

    @Override
    public void careteTable(BillFlowGeneral billFlowGeneralInfo, PdfPCell cell, PdfPTable pdfTable, String printDate) {
        //TODO something
    }

}

2)billfee_rmf类型的回单

package com.hime.aoto.common.hdpdf.impl;

import com.hime.aoto.common.CreateModelNineType;
import com.hime.aoto.common.annotation.BillHandlerType;
import com.hime.aoto.common.hdpdf.HdPdfTable;
import com.hime.aoto.common.utils.DateUtils;
import com.hime.aoto.common.utils.PubUtil;
import com.hime.aoto.project.entity.BillFlowGeneral;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;

/**
 * @author: lijx
 * @date: 2023/1/5 10:13
 * @description: 2)电子回单箱扣费回单 billfee_rmf
 */
@BillHandlerType(source = "billfee_rmf")
public class BillFeeRmfImpl implements HdPdfTable {
    @Override
    public void careteTable(BillFlowGeneral billFlowGeneralInfo, PdfPCell cell, PdfPTable pdfTable, String printDate) {
        //TODO something
    }
}

3)更多实现类…


4.方法调用

== 如果使用if else,每次增加还需要处理条件分支语句,而使用策略模式,每增加一种类型的回单,只需要新增一个实现类,不用修改其他任何代码。==

SpringUtils.getBean(HdPdfTableFactory.class).getHdPdfTable(bill_format, billFlowGeneralInfo, cell, titleTable, printDateTime);

总结

策略模式的优点:
1、干掉繁琐的 if、switch 判断逻辑;

2、代码优雅、可复用、可读性好;

3、符合开闭原则,扩展性好、便于维护;

策略模式的缺点:
1、策略如果很多的话,会造成策略类膨胀;

2、使用者必须清楚所有的策略类及其用途;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值