策略模式的简单使用


前言

提示:简单写一个策略模式的应用例子:

一般应用场景在,多种登录方式(qq,git,账号),多种上传方式(阿里,腾信,本地,七牛云),多种查询方式(本地,es,redis),等等,有多种渠道都在使用一样的功能都可以


一、撸代码

第一步就是简单的 接口类和实现类。用多种上传方式来举例子

接口类

类上面没有注解,如果有的话会粘贴进来的

public interface FileUploadStrategy {
    
    

    String fileUpload(MultipartFile file);
}

接口实现类

这个是七牛云文件上传实现类,阿里上传实现类直接 implements FileUploadStrategy 这个接口就行了。

@Service("aliUploadStrategyImpl")
@RequiredArgsConstructor
public class AliUploadStrategyImpl implements FileUploadStrategy {
    
    

    @Override
    public String fileUpload(MultipartFile file) {
    
    
        // 经过阿里云一系列的接口等操作方式进行上传,此处忽略,最终返回阿里返回的oss地址
        return "https://xxx-dev.oss-cn-shanghai.aliyuncs.com/upload/123/aaa/20221228/123123.png";
    }

}

@RequiredArgsConstructor : Lombok中的一个@RequiredArgsConstructor,简化了一些@Autowired注解,可以减少@Autowired的书写

枚举类

枚举类用来定义上传方式,以及对应的实现类的名称。这个地方的要和@Service(“aliUploadStrategyImpl”)里面的保持一致。

public enum FileUploadModelEnum {
    
    
    /**
     * 本地上传
     */
    LOCAL(0, "本地上传", "localUploadStrategyImpl"),
    /**
     * 七牛云上传
     */
    QIN(1, "七牛云上传", "qiNiuUploadStrategyImpl"),

    /**
     * 阿里云上传
     */
    ALI(2, "阿里云上传", "aliUploadStrategyImpl");

    FileUploadModelEnum(int code, String desc, String strategy) {
    
    
        this.type = code;
        this.desc = desc;
        this.strategy = strategy;
    }


    /**
     * 上传方式
     */
    private final Integer type;
    /**
     * 描述
     */
    private final String desc;
    /**
     * 策略
     */
    private final String strategy;

    public Integer getType() {
    
    
        return type;
    }

    public String getDesc() {
    
    
        return desc;
    }

    public String getStrategy() {
    
    
        return strategy;
    }

    /**
     * 获取策略
     *
     * @param type 模式
     * @return {@link String} 上传策略
     */
    public static String getStrategy(int type) {
    
    
        for (FileUploadModelEnum value : FileUploadModelEnum.values()) {
    
    
            if (value.getType() == (type)) {
    
    
                return value.getStrategy();
            }
        }
        return null;
    }
}

编写策略上下文

@Service
@RequiredArgsConstructor
public class FileUploadStrategyContext {
    
    

    /**
     * 当Map集合的Value为接口类型时,Spring会自动对Map集合进行注入。
     * 其中map集合的key为接口对应实现类的BeanName
     * 其中map集合的vlaue为接口对应实现类的实例
     */
    private final Map<String, FileUploadStrategy> fileUploadStrategyMap;

    /**
     * 执行文件上传策略
     *
     * @param file 文件对象
     * @return {@link String} 文件名
     */
    public String executeFileUploadStrategy(String fileUploadMode, MultipartFile file) {
    
    
         return fileUploadStrategyMap.get(fileUploadMode).fileUpload(file);
    }
}

编写测试类

@Slf4j
@RestController
@RequestMapping("/file")
@RequiredArgsConstructor
public class FileUploadController {
    
    

    private final FileUploadStrategyContext fileUploadStrategyContext;

    @PostMapping("/upload")
    public R compressPic(MultipartFile file) {
    
    
        // TODO 此处代码一般在impl实现类中编写
        // 此处的type应该是某个业务,或者在后台由用户设置的上传方式,一般在用户的设置表中存放
        String strategy = FileUploadModelEnum.getStrategy(2);
        String s = fileUploadStrategyContext.executeFileUploadStrategy(strategy, file);
        return R.data(s);
    }

}

好啦,这样用户在管理端可以随便更改上传方式,代码又不需要变化,如果有新的上传方式,只需要 implements FileUploadStrategy 这个接口,对其他上传方式没有侵害,只需要在自己的实现类里面编写自己的逻辑就行了。完美。

猜你喜欢

转载自blog.csdn.net/gfl1427097103/article/details/129293915