持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情
哈喽,大家好,我是一条。
今天来聊一下策略模式,比较简单且常用的设计模式。属于对象行为模式。
定义
官方
策略(Strategy)模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。
说人话
打游戏,需要策略,是运营还是打架。
拒绝加班也需要策略,婉拒还是直接拒绝。
提前定义好策略的具体实现,想用时直接调用其对应方法就好。
coding
情景再现
我们就来模拟一个拒绝加班的过程,两种策略,直接拒绝和委外拒绝。
新建策略接口
public interface RejectStrategy {
void reject();
}
新建直接拒绝类
public class DirectReject implements RejectStrategy{
@Override
public void reject() {
System.out.println("---------直接拒绝");
}
}
新建委婉拒绝类
public class IndirectReject implements RejectStrategy{
@Override
public void reject() {
System.out.println("--------委婉拒绝");
}
}
加班类
public class OverWork {
private RejectStrategy rejectStrategy;
public OverWork(RejectStrategy rejectStrategy) {
this.rejectStrategy = rejectStrategy;
}
public void addWork(){
System.out.println("今晚加班吧!");
rejectStrategy.reject();
}
}
测试类
public class MainTest {
public static void main(String[] args) {
OverWork overWork = new OverWork(new DirectReject());
OverWork overWork1 = new OverWork(new IndirectReject());
overWork.addWork();
overWork1.addWork();
}
}
输出
结构图
策略模式的主要角色如下:
抽象策略(Strategy)类:公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。 环境(Context)类:持有一个策略类的引用,最终给客户端调用。
应用场景
什么场景用到?
- 使用策略模式可以避免使用多重条件语句,如 if...else 语句、switch...case 语句
- 什么是Spring的 InstantiationStrategy
- 线程池拒绝策略
策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。
缺点
-
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
-
由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。