设计模式-策略者模式(行为型)
2019-08-22 本文已影响0人
NealLemon
定义
- 定义了一组算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户。
- 通俗来讲就是一组应用逻辑,在用户使用某一行为时,在一组应用中可以随意替换。
适用场景
- 有大量的
if....else...
语句时。 - 在很多只有行为不同的类中使用。
- 一个系统需要在动态的几种策略中选择某一种。
优点
- 开闭原则。
- 避免使用
if...else...
或者switch
- 提高算法的保密性和安全性
缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
- 产生过多的策略类。
代码
出于实际出发,我会在web环境下演示策略模式,使用的是springboot
工程。
首先让我们来想一下这么一个业务场景,在现在很多电商都各种搞促销,比如618,双11,近期的816和818等,因此对于促销的方式就属于一种策略。一般有如下几种
- 满减
- 折扣
- 返现
因此我们现在来实现同样买一台电脑,使用不同策略的场景吧。
首先我们需要一个springboot
工程,我们只需要使用 Spring官方的快速搭建即可。我们只需要引入Web依赖。具体搭建方式就不详细说了。
促销统一接口(SaleActivity
)
/**
* 促销活动统一接口
*/
public interface SaleActivity {
//促销
void sale();
}
打折促销(OnSaleSaleActivity
)
/**
* 打折促销实现类
*/
public class OnSaleSaleActivity implements SaleActivity{
@Override
public String sale() {
return "打折促销";
}
}
满减促销(ReduceSaleActivity
)
/**
* 满减促销
*/
public class ReduceSaleActivity implements SaleActivity {
@Override
public String sale() {
return "满减促销";
}
}
返现促销(ReturnSaleActivity
)
/**
* 返现促销
*/
public class ReturnSaleActivity implements SaleActivity{
@Override
public String sale() {
return "返现促销";
}
}
促销 Spring 配置类(SaleConfiguration
)
/**
* 声明spring Bean
*/
@Configuration
public class SaleConfiguration {
@Bean
public OnSaleSaleActivity onSale() {
return new OnSaleSaleActivity();
}
@Bean
public ReduceSaleActivity reduceSale() {
return new ReduceSaleActivity();
}
@Bean
public ReduceSaleActivity returnSale() {
return new ReduceSaleActivity();
}
}
这里就不多做解释了,如果不清楚可以去看看spring文档。
应用层
@RestController
@RequestMapping("/sale")
public class SaleController {
/**
* 依赖查找
*/
@Autowired
private Map<String,SaleActivity> saleActivityMap;
/**
* 应用层选择某一促销策略
* @param saletype
* @return
*/
@GetMapping("/{saletype}")
public String goShopping(@PathVariable("saletype") String saletype) {
SaleActivity saleActivity = saleActivityMap.get(saletype);
return saleActivity.sale();
}
}
在这里我们直接使用 spring 的依赖查找 默认装配所有策略。
UML 类图
strategy.jpg这里不是标准的策略UML类图,因为使用了spring 的特性,但是看右侧我们还是可以清晰的看出来 行为不同的策略的实现类的结构。
测试
我们启动springboot
的引导类,相当于启动了一个web项目。然后我们使用postman 来模拟用户请求不同策略查看实现结果。
我们发现在请求不同的策略时,我们只需要一个接口可以完成不同的策略替换,这就属于策略者模式的一种。
其他开源
在spring 中 视图内容协商相关内容中,使用了策略者模式,具体我就不过多解释了,可以参看一下
小结
策略者模式在需求变更或者行为繁多的情况下还是很有用武之地的。希望大家灵活的运用起来。