简介
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
策略模式的角色和职责
1.Strategy:策略(算法)抽象
2.ConcreteStrategy:各种策略(算法)的具体实现
3.Context:策略的外部封装类,或者说策略的容器。根据不同的策略执行不同的行为。策略由外部环境决定。
java.util.concurrent中的ThreadPoolExecutor类在实现拒绝策略的时候就是用的策略模式
UML图
代码
Strategy策略接口
public interface RejectedExecutionHandler {
void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}
ConcreteStrategy实现具体策略算法的四个类。实际上这四个类是ThreadPoolExecutor中的静态内部类,但是这个跟策略模式没有必然联系。
public static class CallerRunsPolicy implements RejectedExecutionHandler {
public CallerRunsPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
}
public static class AbortPolicy implements RejectedExecutionHandler {
public AbortPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
public static class DiscardPolicy implements RejectedExecutionHandler {
public DiscardPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
}
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
public DiscardOldestPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
}
Context:策略的外部封装类ThreadPoolExecutor(跟策略模式无关的源码不贴,以免混淆对策略模式的理解)
public class ThreadPoolExecutor {
private volatile RejectedExecutionHandler handler;
public ThreadPoolExecutor(/*跟策略模式无关的代码不贴*/RejectedExecutionHandler handler) {
//... 跟策略模式无关的代码不贴
this.handler = handler;
}
final void reject(Runnable command) {
handler.rejectedExecution(command, this);
}
//... 跟策略模式无关的代码不贴
}
使用(跟策略模式无关的源码不贴,以免混淆对策略模式的理解)实际上这四个类是ThreadPoolExecutor中的静态内部类,但是这个跟策略模式没有必然联系。
package com.sid;
import java.util.concurrent.*;
/**
* @program: thread-test
* @description:
* @author: Sid
* @date: 2019-01-15 17:02
* @since: 1.0
**/
public class ThreadPoolExecutorTest {
public static void main(String[] args) {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
/*...跟策略模式无关的代码、参数不贴*/
new ThreadPoolExecutor.AbortPolicy());
pool.execute( /*...跟策略模式无关的代码、参数不贴*/);
pool.shutdown();
}
}
这里在Context角色(即是ThreadPoolExecutor类)的构造函数入参的时候,传入不同的ConcreteStrategy角色(即是实现具体策略算法类),在执行策略方法(rejectedExecution)的时候会执行到传入的ConcreteStrategy角色实现的策略方法中。