策略模式

一、什么是策略模式以及策略模式功能

1.1 为什么需要策略模式?

1)完成一项任务,往往可以有多种不同的方式,每一种方式称为一个策略,我们可以根据环境或者条件的不同选择不同的策略来完成该项任务。
2)在软件系统中,很多算法可以实现某一功能,比如查找、排序。这里以查找算法为例说明,如果我们需要提供多种查找算法,可以将这些算法写在一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法;当然也可以将这些查找算法封装在一个统一的方法中,通过if…else…等条件判断语句来进行选择。但是这两种实现方式有个弊端,如果需要增加一种新的查找算法,需要修改封装算法类的源代码;更换查找算法,也需要修改客户端调用代码。维护起来比较困难。
3)除了提供专门的查找算法类之外,还可以在客户端程序中直接包含算法代码,这种做法更不可取,将导致客户端程序庞大而且难以维护,如果存在大量可供选择的算法时问题将变得更加严重。(这里的在客户端中包含算法代码的意思就好比我们在包含main函数的类里去实现算法,而不专门提供封装算法的类)
4)为了解决这些问题,可以定义一些独立的类来封装不同的算法,每一个类封装一个具体的算法,在这里,每一个封装算法的类我们都可以称之为策略(Strategy),为了保证这些策略的一致性,一般会用一个抽象的策略类来做算法的定义,而具体每种算法则对应于一个具体策略类。

1.2 什么是策略模式?

策略模式(Strategy Pattern):定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。

二、策略模式结构和UML图

2.1 策略模式结构

策略模式包含如下角色:

  • Context: 环境类
  • Strategy: 抽象策略类
  • ConcreteStrategy: 具体策略类

其中Context类持有Strategy的引用,ConcreteStrategy实现Strategy接口。

2.2 策略模式UML图

2.3 策略模式Demo

以最近火到爆炸的波音737飞机为例,写个demo。

首先定义抽象策略类 

/**
 * 抽象策略类 自动控制系统
 * */
public interface AutomaticControlSystem {
    void automaticControl();
}

然后定义具体策略类

/**
 * 具体策略类
 * */
public class AntiStallController implements AutomaticControlSystem {
    @Override
    public void automaticControl() {
        System.out.println("--起飞时防失速自动校正操作--");
    }
}

/**
 * 具体策略类
 * */
public class AutoFlyController implements AutomaticControlSystem {
    @Override
    public void automaticControl() {
        System.out.println("--自动巡航操作--");
    }
}

/**
 * 具体策略类
 * */
public class AutomaticLandingController implements AutomaticControlSystem {
    @Override
    public void automaticControl() {
        System.out.println("--自动降落操作--");
    }
}

 

接着定义Context环境类

/**
 * 抽象环境类
 * */
public abstract class Boeing {
    AutomaticControlSystem automaticControlSystem;

    public void autoController(){
        automaticControlSystem.automaticControl();
    }
    
}
/**
 * 具体环境类
 * */
public class Boeing737 extends Boeing {

    public Boeing737(AutomaticControlSystem automaticControlSystem) {
          super.automaticControlSystem = automaticControlSystem;
    }

    public void autoController(){
        automaticControlSystem.automaticControl();
    }
}

最后是测试类:

/**
 * 测试类
 * */
public class Test {
    public static void main(String[] args) {
        //传入不同的策略即可
        new Boeing737(new AntiStallController()).autoController();
        new Boeing737(new AutoFlyController()).autoController();
        new Boeing737(new AutomaticLandingController()).autoController();
    }
}

运行结果:

 

三、策略模式在JDK中的应用

3.1 比较器Comparator

     在Java的集合框架中,经常需要通过构造方法传入一个比较器Comparator,或者创建比较器传入Collections的静态方法中作为方法参数,进行比较排序等,使用的是策略模式。

     在该比较架构中,Comparator就是一个抽象的策略;一个类实现该结构,并实现里面的compare方法,该类成为具体策略类;Collections类就是环境角色,他将集合的比较封装成静态方法对外提供api。

3.2 ThreadPoolExecutor中的四种拒绝策略

     在创建线程池时,需要传入拒绝策略,当创建新线程使当前运行的线程数超过maximumPoolSize时,将会使用传入的拒绝策略进行处理。

  • AbortPolicy:直接抛出异常。
  • CallerRunsPolicy:只用调用者所在线程来运行任务。
  • DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。
  • DiscardPolicy:不处理,丢弃掉。

     这里使用的就是策略模式。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值