1. 啥是策略模式?
https://www.runoob.com/design-pattern/strategy-pattern.html 程序可以在运行时,动态地决定需要使用哪种策略来处理业务操作. 主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护,并且难以在运行时动态调整(动态调整:这就需要一些技巧)。
1. 定义策略模式的主接口、两个实现类
public interface UploadStrategy {
void upload();
}
---
public class FtpUploadStrategy implements UploadStrategy {
@Override
public void upload() {
System.out.println("==========ftp文件开始上传……");
}
}
---
public class OssUploadStrategy implements UploadStrategy {
@Override
public void upload() {
System.out.println("==========oss文件开始上传……");
}
}
2. 定义动态环境UploadContext类 —— 动态感知环境变化,动态调整需要实现的策略类,这部分可以交给SpringBoot的@PostConstructor来根据xml配置文件来动态初始化选择
public class UploadContext implements UploadStrategy {
private UploadStrategy uploadStrategy;
public UploadContext(UploadStrategy uploadStrategy) {
this.uploadStrategy = uploadStrategy;
}
@Override
public void upload() {
uploadStrategy.upload();
}
}
3. 主测试类
public class Main {
private UploadContext uploadContext;
@Test
public void strategyTest() {
uploadContext = new UploadContext(new OssUploadStrategy());
uploadContext.upload();
uploadContext = new UploadContext(new FtpUploadStrategy());
uploadContext.upload();
}
}
测试结果
==========oss文件开始上传......
==========ftp文件开始上传......
4.使用 Lambda 重构面向对象
/**
* 使用lambda表达式进行简化 不需要新增新的实现类,就可以轻松添加策略,比如下面的第三种策略"hdfs文件开始上传"
*/
@Test
public void strategyLambdaTest() {
uploadContext = new UploadContext(() -> System.out.println("==========oss文件开始上传......"));
uploadContext.upload();
uploadContext = new UploadContext(() -> System.out.println("==========ftp文件开始上传......"));
uploadContext.upload();
uploadContext = new UploadContext(() -> System.out.println("==========hdfs文件开始上传......"));
uploadContext.upload();
}
缺点: lambda表达式可以简化的前提是UploadStrategy 只有一个接口方法,即函数接口,大于一方法lambda表达式会失效;这种简化其实就是把实现方法提前写在了lambda表达式中
其他:实际使用还是需要灵活调整,设计模式是为了重构具体的代码耦合问题,是为了解决问题的!不是纯粹的为了炫技巧,代码安全性和易读性也是需要考虑和权衡的。
还可以融合springboot,发挥一些web的独特特性。