1. 何为策略
策略,英文strategy,音标[ˈstrætədʒi],来来来,此处read after me大声读三遍,什么重音、清辅音、浊辅音我都玩的有模有样,十分优秀吭。
策略就是方法,办法,方针,计谋差不多的意思,策略模式就如把三十六计汇聚成一本书,一块研究管理,不然的话如此多的策略,打起仗来临时抱佛脚也不知道该去哪里抱啊。
所以策略模式就是把策略归置好,并且通过一个集中的环境去读取后使用。例如三十六计,就是把三十六中计谋集中归置到书本(集中的环境)中,代后人调阅,也不用管后人到底是古代人,还是现代人,还是中国人,还是外国人,就是这么牛X吭。
2. 举个栗子
光说不练是假把式,手中必须有栗子才是真本事,此处我们举个现实的编程实例。
比如现在我们有很多种数字加密算法,我们应该把这些不同的算法(策略)封装起来,后续不管是网页调用也好,是APP调用也好都可以直接拿过来使用。所以此处就是一个比较标准的策略模式使用场景。
2.1 抽象策略
首先分析下我们的策略是什么样的策略,实际上就是对数字加密,因此封装一个接口IEncryptStrategy,注意这个命令中I表示这是一个接口,Encrypt表示加密,Strategy表示策略,综合起来讲,这是一个加密策略的接口。代码如下:
package org.demo.strategy;
/**
* @theme 加密策略接口
* @author maoge
* @date 2019-12-10
*/
public interface IEncryptStrategy {
/**
* 对一个数字进行加密
*/
public double encrypt(double input);
}
2.2 具体策略
抽象策略是为了定义一个标准,只有符合标准的才能纳入该类策略,比如此处必须是能对数字加密的策略才行,此处我们实现两个牛X的加密算法,稳!
package org.demo.strategy;
/**
* @theme 加法加密策略
* @author maoge
* @date 2019-12-10
*/
public class AddEncryptStrategy implements IEncryptStrategy {
/**
* 将原来的值先+1,再加3,再+2,如此复杂的加密算法,一般人想不到哈
*/
@Override
public double encrypt(double input) {
return input + 1 + 3 + 2;
}
}
package org.demo.strategy;
/**
* @theme 乘法加密策略
* @author maoge
* @date 2019-12-10
*/
public class MultiplyEncryptStrategy implements IEncryptStrategy {
/**
* 乘法加密——为高端加密算法代言
*/
@Override
public double encrypt(double input) {
return input * 10;
}
}
2.3 调用环境
策略有了之后,最好放在一个统一的管理环境中,便于灵活调度。就好比要查询计谋可去看《三十六计》书,要调用加密算法就使用加密算法上下文环境。
package org.demo.strategy;
/**
* @theme 加密算法上下文环境
* @author maoge
* @date 2019-12-10
*/
public class EncryptContext {
/**
* 可保存任意策略
*/
private IEncryptStrategy strategy;
public EncryptContext(IEncryptStrategy strategy) {
this.strategy = strategy;
}
/**
* 调用保存的策略
*/
public double encrypt(double input) {
return strategy.encrypt(input);
}
}
2.4 调用示例
package org.demo.strategy;
/**
* 常规调用实例
*/
public class NormalUseStrategy {
public static void main(String[] args) {
EncryptContext context = new EncryptContext(new AddEncryptStrategy());
System.out.println("加法策略:" + context.encrypt(1));
context = new EncryptContext(new MultiplyEncryptStrategy());
System.out.println("乘法策略:" + context.encrypt(1));
}
}
2.5 借助枚举与工厂模式规范调用
上面的调用示例对策略生成的管理太随意了,我们可以借助枚举和工厂模式来规范之,代码如下:
加密方法枚举:
package org.demo.strategy;
public enum EncryptStrategyEnum {
ADD, MULTIPLY;
}
工厂模式的环境类:
package org.demo.strategy;
/**
* @theme 加密算法上下文环境
* @author maoge
* @date 2019-12-10
*/
public class EncryptContext {
/**
* 可保存任意策略
*/
private IEncryptStrategy strategy;
/**
* 根据枚举生成策略
*/
public EncryptContext(EncryptStrategyEnum encryptStrategyEnum) {
if (encryptStrategyEnum == EncryptStrategyEnum.ADD) {
strategy = new AddEncryptStrategy();
} else {
strategy = new MultiplyEncryptStrategy();
}
}
/**
* 调用保存的策略
*/
public double encrypt(double input) {
return strategy.encrypt(input);
}
}
调用示例:
package org.demo.strategy;
/**
* 调用实例
*/
public class Demo {
public static void main(String[] args) {
EncryptContext context = new EncryptContext(EncryptStrategyEnum.ADD);
System.out.println("加法策略:" + context.encrypt(1));
context = new EncryptContext(EncryptStrategyEnum.MULTIPLY);
System.out.println("乘法策略:" + context.encrypt(1));
}
}