提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
公司项目中有这样一个导出表格的需求,需要根据不同的设备型号,导出不同的表格,开始的时候为了快速的开发出来(主要是对需求的理解不够深入而且时间有限)在controller中使用了大量的if-else if -else if…-else,当再次增加新型号设备时,修改这段代码及其头疼,特别是时间长了,忘记了一些以前的逻辑,每次都得去捋一遍以前的逻辑是啥。近期在看设计模式相关的内容,发现可以使用简单工厂+策略模式解决这个问题。以此文来做记录。
提示:以下是本篇文章正文内容,下面案例可供参考
一、什么是策略模式和简单工厂
- 策略模式
- 定义:该模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响使用算法的客户(此处的客户是指使用该策略的java类)
- 抽象策略类(Strategy):定义一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
- 具体策略(Concrete Strategy):实现了抽象策略定义的接口的类,提供了具体的算法实现。
- 环境上下文类(Strategy Context):持有策略类的类,最终给客户端调用的类
- 工厂模式:简而言之,工厂模式就是用来产生对象的类
二、代码实现
代码实现没有具体的业务,只用了打印来代替
- 创建策略接口类
代码如下(示例):
package com.example.stratage.strategy;
/**
* @className: Stratage
* @description: TODO 类描述
* @author: xufh
* @date: 2022/3/29
*/
public interface Stratage {
void eportExcel();
}
- 为不同型号的设备实现策略接口
package com.example.stratage.strategy.impl;
import com.example.stratage.strategy.Stratage;
import org.springframework.stereotype.Component;
/**
* @className: Model2028Stratage
* @description: 2028型设备策略类实现
* @author: xufh
* @date: 2022/3/29
*/
@Component
public class Model2028Stratage implements Stratage {
@Override
public void eportExcel() {
System.out.println("2028型仪器导出数据~~~~~~~~~~~~~~");
}
}
package com.example.stratage.strategy.impl;
import com.example.stratage.strategy.Stratage;
import org.springframework.stereotype.Component;
/**
* @className: Model2029Stratage
* @description: TODO 类描述
* @author: xufh
* @date: 2022/3/29
*/
@Component
public class Model2029Stratage implements Stratage {
@Override
public void eportExcel() {
System.out.println("2029型仪器导出数据~~~~~~~~~~~~~~");
}
}
package com.example.stratage.strategy.impl;
import com.example.stratage.strategy.Stratage;
import org.springframework.stereotype.Component;
/**
* @className: Model3012kStratage
* @description: TODO 类描述
* @author: xufh
* @date: 2022/3/29
*/
@Component
public class Model3012kStratage implements Stratage {
@Override
public void eportExcel() {
System.out.println("3012k型仪器导出数据~~~~~~~~~~~~~~~~~~~");
}
}
- 创建策略上下文切换类
package com.example.stratage.context;
import com.example.stratage.strategy.Stratage;
import org.springframework.stereotype.Component;
/**
* @className: StrategyContext
* @description: TODO 类描述
* @author: xufh
* @date: 2022/3/29
*/
@Component
public class StrategyContext {
private Stratage stratage;
public StrategyContext() {
}
public void exportExcel() {
if (stratage != null) {
stratage.eportExcel();
}
}
public Stratage getStratage() {
return stratage;
}
public void setStratage(Stratage stratage) {
this.stratage = stratage;
}
}
- 创建工厂类
package com.example.stratage.factory;
import com.example.stratage.strategy.Stratage;
import com.example.stratage.strategy.impl.Model2028Stratage;
import com.example.stratage.strategy.impl.Model2029Stratage;
import com.example.stratage.strategy.impl.Model3012kStratage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
/**
* @className: StrategyFactory
* @description: TODO 类描述
* @author: xufh
* @date: 2022/3/29
*/
@Component
public class StrategyFactory {
private static final Map<String, Stratage> strategies = new HashMap<>();
public StrategyFactory() {
}
private Model3012kStratage model3012kStratage;
private Model2028Stratage model2028Stratage;
private Model2029Stratage model2029Stratage;
@Autowired
public StrategyFactory(Model3012kStratage model3012kStratage, Model2028Stratage model2028Stratage, Model2029Stratage model2029Stratage) {
this.model3012kStratage = model3012kStratage;
this.model2028Stratage = model2028Stratage;
this.model2029Stratage = model2029Stratage;
strategies.put("2028", model2028Stratage);
strategies.put("2029", model2029Stratage);
strategies.put("3012k", model3012kStratage);
}
@PostConstruct
public void initStrategies() {
strategies.put("2028", new Model2028Stratage());
strategies.put("2029", new Model2029Stratage());
strategies.put("3012k", new Model3012kStratage());
}
public Stratage getStratage(String type) {
if (StringUtils.isEmpty(type)) {
throw new RuntimeException("空参数");
} else {
return strategies.get(type);
}
}
}
- 客户端程序代码
package com.example.stratage.controller;
import com.example.stratage.context.StrategyContext;
import com.example.stratage.factory.StrategyFactory;
import com.example.stratage.strategy.Stratage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @className: DemoController
* @description: TODO 类描述
* @author: xufh
* @date: 2022/3/29
*/
@RestController
@RequestMapping("/excel")
public class DemoController {
@Autowired
private StrategyFactory strategyFactory;
@Autowired
private StrategyContext strategyContext;
@GetMapping("/{instModel}")
public void export(@PathVariable("instModel") String instModel) {
Stratage stratage = strategyFactory.getStratage(instModel);
if (stratage == null) {
System.out.println("stratage为空");
} else {
strategyContext.setStratage(stratage);
strategyContext.exportExcel();
}
}
}
总结
以上就是这次的内容,设计模式的实际落地,通过工厂加策略模式去掉了大量的if else if 。。。,实现了解耦。当再有新的型号的设备需要导出时,只要实现策略接口,并在工厂中添加进去就可以了,不需要修改原来代码。语言表达能力比较差,多交流。。。。