策略模式,以及最近用到的策略模式

策略模式

策略模式的目的是使程序在运行过程中可以根据需要对同一方法采取不同的策略执行,关键是根据需要通过共同接口调用子类不同的方法

优点:自由切换算法,无需写条件判断语句

类图:

策略模式的 UML 图

 

在公司项目中使用的策略模式

目前有一个模块是节点系统,要部署到不同的机构中,本来打算文件全部存储到Oss中,现在有一个机构要求把文件可以存储到自己的服务器中,为了避免代码变得混乱,我决定采用策略模式

1. 策略类的基类

我定义了FileSaver来表示公共接口

//保存文件抽象接口
public interface FileSaver {
  //通过inputStream上传文件并返回url
  public String saveFileStream(InputStream inputStream, String fileName) throws IOException;
  //通过文件路径上传文件并返回url
  public String saveFilePath(String path);

  public String saveFilePath(String path, String fileName);
}

2. 定义策略类,主要是定义了本地存储和远程Oss存储,这里列出本地存储的代码

@Component("LocalFileSaver")
public class LocalFileSaver implements FileSaver{
  @Override
  public String saveFileStream(InputStream inputStream, String fileName) {
具体实现
  }
  @Override
  public String saveFilePath(String path) {
具体实现
  }

  @Override
  public String saveFilePath(String path, String fileName) {
具体实现
  }
}

这里将类交给了Spring管理

3. 定义context类

public class FileSaverContext {
  FileSaver fileSaver;
  public FileSaverContext(FileSaver fileSaver) {
      this.fileSaver = fileSaver;
  }
  public String uploadFileStream(InputStream inputStream, String fileName) throws IOException {
      return fileSaver.saveFileStream(inputStream, fileName);
  }
  public String uploadFilePath(String path) {
      return fileSaver.saveFilePath(path);
  }
  public String uploadFilePath(String path, String fileName) {
      return fileSaver.saveFilePath(path, fileName);
  }
}

4. 配置Spring,根据不同需要注入context

@Configuration
public class MyBeanConfiguration implements ApplicationContextAware {
  @Value("${配置上传策略}")
  String fileSaveStrategy;
  ApplicationContext context;
  @Bean
  public FileSaverContext getFileSaverContext() {
      return new FileSaverContext((FileSaver)context.getBean(fileSaveStrategy));
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
      context = applicationContext;
  }
}

通过这样做,要上传文件的时候直接调用spring管理的FileSaverContext即可,如果要改变策略只需要修改一下配置文件中地上传策略就可以了

 

5. 后续扩展

假设后续公司要求搞其他的上传方法,不管是要用vsftpd搞个ftp服务器来上传文件还是自己搞个http服务器还是搞个腾讯云华为云whatever云来上传文件都可以很容易地扩展

步骤如下:

1. 实现FileSaver接口,用@Component为其取名

2. 在配置文件中配置这个名字

任何代码都不用更改,整个系统照常运行

原文地址:https://www.cnblogs.com/PanYuDi/p/14798301.html