public interface PerformanceProcessor {
//加载分析报告
void viewHospitalPerformance(HttpServletRequest request, HttpServletResponse response,String key);
//预览分析报告
void read(HttpServletRequest request, HttpServletResponse response, QueryParam param);
//下载分析报告
void down(HttpServletRequest request, HttpServletResponse response, QueryParam param);
}
public abstract class AbstractPerformance implements PerformanceProcessor {
@Autowired
private Environment env;
@Override
public void viewHospitalPerformance(HttpServletRequest request, HttpServletResponse response,String key) {
String filePath = ;
if ("dept".equalsIgnoreCase(key)) {
filePath = env.getProperty("xxxxx");
}
if ("xxxxx".equalsIgnoreCase(key)) {
filePath = xxxx;
}
}
}
@Component("deptPerformanceProcessor")
@ConditionalOnMissingBean(name = {"xxxxx"})
public class DeptPerformanceProcessor extends AbstractPerformance {
}
@Controller
@RequestMapping("/xxxx")
public class PerformanceReport {
private final Map<String, PerformanceProcessor> performanceComponentMap;
public PerformanceReport(Map<String, PerformanceProcessor> performanceComponentMap) {
this.performanceComponentMap = performanceComponentMap;
}
@GetMapping("/xxxxx")
@ApiOperation("加载报告")
public void view(HttpServletRequest request, HttpServletResponse response, String hospitalType) throws Exception {
goToDept(hospitalType).view(request, response, hospitalType);
}
@GetMapping
public void xxxxxx();
private PerformanceProcessor goToDept(String hospitalType) {
PerformanceProcessor p = null;
for (String key : performanceComponentMap.keySet()) {
if (key.toLowerCase().contains("xxxx") && hospitalType.equals("xxxx")) {
p = performanceComponentMap.get(key);
break;
}
if(xxxx);
}
return p;
}
优点
-
灵活性和可扩展性
- 策略模式:通过
Map<String, PerformanceProcessor>
,可以动态地添加、替换或移除具体的处理逻辑,而无需修改现有代码。这使得系统更容易适应需求变化。 - 模板方法模式:
AbstractPerformance
定义了算法的骨架,子类可以灵活地扩展或重写某些步骤,而不会影响整体流程。
- 策略模式:通过
-
代码复用
- 模板方法模式:
AbstractPerformance
可以将通用的逻辑(如初始化、校验、日志记录等)放在父类中,子类只需关注具体的业务逻辑实现。这减少了代码重复,提高了复用性。 - 策略模式:将不同的处理逻辑封装到独立的类中,可以在多个地方复用这些逻辑,而不需要重复编写代码。
- 模板方法模式:
-
解耦和单一职责
- 策略模式:每个
PerformanceProcessor
实现类只负责一个具体的处理逻辑,符合单一职责原则。这使得代码更易于维护和测试。 - 模板方法模式:
AbstractPerformance
负责定义算法的整体流程,而具体的实现细节由子类完成,实现了高层逻辑与底层实现的解耦。
- 策略模式:每个
-
易于测试
- 策略模式:每个策略类可以独立测试,测试用例更简单、更聚焦。
- 模板方法模式:可以通过模拟子类来测试父类的通用逻辑,确保算法的整体流程正确。
-
可读性和可维护性
- 模板方法模式:算法的整体流程在父类中清晰可见,便于理解和维护。
- 策略模式:通过将不同的逻辑分离到独立的类中,代码结构更清晰,便于阅读和维护。
缺点
-
复杂度增加
- 策略模式:如果策略类过多,可能会导致类的数量膨胀,增加系统的复杂度。
- 模板方法模式:如果父类的算法流程过于复杂,可能会增加理解和维护的难度。
-
性能开销
- 策略模式:在运行时动态选择策略可能会引入一定的性能开销(如查找
Map
中的策略)。 - 模板方法模式:如果父类的通用逻辑过于复杂,可能会影响性能。
- 策略模式:在运行时动态选择策略可能会引入一定的性能开销(如查找
-
设计过度
- 如果业务逻辑本身非常简单,使用这种设计模式可能会显得过度设计,增加不必要的复杂性。
-
继承的局限性
- 模板方法模式:由于使用了继承,子类与父类之间存在强耦合关系。如果父类的逻辑发生变化,可能会影响所有子类。
- 如果子类需要继承其他类,Java 的单继承机制可能会限制这种设计。
-
策略选择的复杂性
- 策略模式:如果策略的选择逻辑非常复杂,可能会导致
Map
的管理和维护变得困难。
- 策略模式:如果策略的选择逻辑非常复杂,可能会导致
适用场景
这种设计模式组合适用于以下场景:
- 需要动态选择不同的处理逻辑(策略模式)。
- 算法的整体流程固定,但某些步骤需要灵活扩展或重写(模板方法模式)。
- 需要将通用逻辑与具体逻辑分离,以提高代码复用性和可维护性。
总结
优点 | 缺点 |
---|---|
灵活性和可扩展性 | 复杂度增加 |
代码复用 | 性能开销 |
解耦和单一职责 | 设计过度 |
易于测试 | 继承的局限性 |
可读性和可维护性 | 策略选择的复杂性 |
在实际开发中,需要根据具体需求和场景权衡利弊,避免过度设计,同时确保代码的灵活性和可维护性。