前言
本文以Java语言为主,分析包括JDK、Spring、MyBatis、Guava、org.apache.xxx中,等一些优秀的开源代码、项目,在这些开源代码、项目中都包含了大量的设计模式,通过对它们进行分析,能够快速帮助我们学会设计模式的使用方式,由理论过渡到实践中,进而真正了解设计模式的思想,由于内容较多,所以每个设计模式单独写一篇文章,需要了解其他模式请点击对应链接跳转。
策略模式
策略模式比较简单,很多地方都有用到,可能并不是按照标准的模式,但思想还是一致的
org.apache.commons:commons-lang3
/**
* 单个日期字段的分析策略
*/
private static abstract class Strategy {
/**
* Is this field a number? The default implementation returns false.
*
* @return true, if field is a number
*/
boolean isNumber() {
return false;
}
abstract boolean parse(FastDateParser parser, Calendar calendar, String source, ParsePosition pos, int maxWidth);
}
对应三种不同的策略
StrategyAndWidth 类似策略模式中的环境类
private static class StrategyAndWidth {
final Strategy strategy;
final int width;
StrategyAndWidth(final Strategy strategy, final int width) {
this.strategy = strategy;
this.width = width;
}
int getMaxWidth(final ListIterator<StrategyAndWidth> lt) {
if (!strategy.isNumber() || !lt.hasNext()) {
return 0;
}
final Strategy nextStrategy = lt.next().strategy;
lt.previous();
return nextStrategy.isNumber() ? width : 0;
}
}
最后使用的地方
JDK
JDK中提供的线程池,其中拒绝策略的使用方式也用到了策略模式的思想
RejectedExecutionHandler策略接口类
public interface RejectedExecutionHandler {
/**
* Method that may be invoked by a {@link ThreadPoolExecutor} when
* {@link ThreadPoolExecutor#execute execute} cannot accept a
* task. This may occur when no more threads or queue slots are
* available because their bounds would be exceeded, or upon
* shutdown of the Executor.
*
* <p>In the absence of other alternatives, the method may throw
* an unchecked {@link RejectedExecutionException}, which will be
* propagated to the caller of {@code execute}.
*
* @param r the runnable task requested to be executed
* @param executor the executor attempting to execute this task
* @throws RejectedExecutionException if there is no remedy
*/
void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}
定义了四种不同的具体策略角色
ThreadPoolExecutor相当于策略模式中的环境类,RejectedExecutionHandler策略接口类做为其成员变量
通过构造方法赋值
最后直接使用即可
MyBatis
Executor相当于策略接口类,定义了很多接口方法
具体的策略类
DefaultSqlSession相当于策略环境类,也是通过构造方法的方式生成引入策略类Executor
获取具体策略类
把获取的策略类通过构造方法的方式赋给策略环境类的属性
最后直接使用