策略模式——拒绝加班

155 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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
  • 线程池拒绝策略

策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。

缺点

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。

  • 由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。