前言
提示:简单写一个策略模式的应用例子:
一般应用场景在,多种登录方式(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 这个接口,对其他上传方式没有侵害,只需要在自己的实现类里面编写自己的逻辑就行了。完美。