一. 简介
1. 什么是策略模式?
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
2. 策略模式的应用场景?
如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为
一个系统需要动态地在几种算法中选择一种
如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现
二. 策略模式的使用
我们来模拟一个商城系统创建不同活动的需求,假设我们需要根据传入的type来判断创建所要创建的活动,传统的方式我们可能或通过if()---else()的方式去判断索要创建的活动类类型,如果类型多的话这样的判断就会显得代码很凌乱。那么我们可以尝试着用策略模式去优化这种逻辑。
下面我们模拟三种不同活动的创建
创建策略枚举类
/**
* @author gf
* @date 2023/2/7
*/
@Getter
@AllArgsConstructor
public enum ActivityTypeEnum {
MANJIAN(101, "满减活动"),
MANZHE(102, "满折活动"),
PRESALE(103, "预售活动");
int type;
String desc;
}
创建活动接口
/**
* @author gf
* @date 2023/2/7
*/
public interface ActivityService {
/**
* 创建活动
*
* @return
*/
void createActivity();
/**
* 获取订单类型
*
* @return
*/
ActivityTypeEnum type();
}
创建活动实现类
接下来我们分别创建满减,满折和预售的实现类
满减实现类:
/**
* @author gf
* @date 2023/2/7
*/
@Slf4j
@Service
public class ManJianActivityImpl implements ActivityService {
@Override
public void createActivity() {
log.info("----创建满减活动----");
}
@Override
public ActivityTypeEnum type() {
return ActivityTypeEnum.MANJIAN;
}
}
满折实现类:
/**
* @author gf
* @date 2023/2/7
*/
@Slf4j
@Service
public class ManZheActivityImpl implements ActivityService {
@Override
public void createActivity() {
log.info("----创建满折活动----");
}
@Override
public ActivityTypeEnum type() {
return ActivityTypeEnum.MANZHE;
}
}
预售实现类:
/**
* @author gf
* @date 2023/2/7
*/
@Slf4j
@Service
public class PreSaleActivityImpl implements ActivityService {
@Override
public void createActivity() {
log.info("----创建预售活动----");
}
@Override
public ActivityTypeEnum type() {
return ActivityTypeEnum.PRESALE;
}
}
创建活动创建通用接口
/**
* @author gf
* @date 2023/2/7
*/
@RestController
public class ActivityController {
@Autowired
private List<ActivityService> activityService;
/**
* 创建活动
*
* @param type 活动类型
* @return
*/
public void createActivity(int type) {
/**
* 根据动类型,找到对应的处理器
*/
Optional<ActivityService> any = activityService.stream().filter(f -> f.type().getType() == type).findAny();
/**
* 没有对应的处理器
*/
if (!any.isPresent()) {
throw new RuntimeException("没有找到相应的活动实现");
}
// 创建订单
any.get().createActivity();
}
}
测试活动创建
@SpringBootTest
class DesignApplicationTests {
@Autowired
private ActivityController activityController;
@Test
void contextLoads() {
activityController.createActivity(ActivityTypeEnum.MANJIAN.getType());
}
}
搞定,看是不是很方便,省去了很多的if--else的判断和接口的注入
三. 策略模式的优缺点
优点:
算法可以自由切换;
避免使用多重判断;
拓展性良好,增加一个策略只需要实现接口即可;
缺点:
策略类数量会增多,每个策略都是一个类,复用性很小;
所有的策略类都需要对外暴露