1. 策略模式简介
策略模式的主要核心是:定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法发生变化,不会影响到使用算法的用户。
举例:最简单的例子是密码加密。根据你不同的要求返回不同的密码。你也可以将各种算法对象封装起来,通过不同对象来产生不同密码(就是简单工厂模式)。但是简单工厂模式一般都是用来解决对象创建问题,而且如果用户要每天都使用一种不同的加密方法,就会导致我们频繁地去修改对象生产类,频繁更新代码。所以我们这边使用策略模式,直接将加密算法封装成策略家族中的一个即可。
2. 策略模式代码分析
我们先来看一下算法抽象类,它是算法的公共接口。
public abstract class Strategy {
//算法方法
public abstract String AlgorithmInterface(String psw);
}
接下来是实现算法接口的具体算法:
public class ConcreteStrategyA extends Strategy{
//重写父类算法,这边称之为A方法
public String AlgorithmInterface(String psw) {
psw = psw+"AAA";
return psw;
}
}
public class ConcreteStrategyB extends Strategy{
//重写父类算法,这边称之为B方法
public String AlgorithmInterface(String psw) {
psw = psw+"BBB";
return psw;
}
}
我们接着定义一个使用策略对象方法的类,这边称之为上下文类:
public class Context {
//持有算法对象引用
Strategy strategy;
//初始化时,必须传入一个具体的策略方法
public Context(Strategy strategy){
this.strategy = strategy;
}
//根据具体的策略对象,调用其算法的方法
public String useAlogorithm(String psw){
return strategy.AlgorithmInterface(psw);
}
}
最后就是我们客户中调用算法的代码:
public class test {
public static void main(String[] args) {
Context context;
//使用A方法
context = new Context(new ConcreteStrategyA());
System.out.println(context.useAlogorithm("这是哪个算法?答:"));
//使用A方法
context = new Context(new ConcreteStrategyB());
System.out.println(context.useAlogorithm("这是哪个算法?答:"));
}
}
运行的结果如下:
这是哪个算法?答:AAA
这是哪个算法?答:BBB
3. 模式提升
在这边可能会有朋友要说,这不是和简单工厂模式一样吗?在客户端判断使用哪个方法和在客户端判断使用哪个工厂对象一样繁琐么,而且也如果要改,也还是需要去修改客户端的运行代码。
所以我们在这边可以使用简单工厂模式 + 策略模式来解决这个问题。
//将策略模式与简单工厂模式相结合
public class Context {
//持有算法对象引用
Strategy strategy;
//初始化时,必须传入一个具体的策略方法
public Context(String type){
if(type.equals("ConcreteStrategyA")){
this.strategy = new ConcreteStrategyA();
}
if(type.equals("ConcreteStrategyB")){
this.strategy = new ConcreteStrategyB();
}
}
//根据具体的策略对象,调用其算法的方法
public String useAlogorithm(String psw){
return strategy.AlgorithmInterface(psw);
}
}
策略模式的优点就是: 降低了算法与算法之间的联系。与简单工厂模式一样,只侧重点不同。我们平时使用MD5或是SHA加密的时候,不就是直接给个加密算法名称而已。这样降低了用户使用代码和算法之间的紧密耦合。