策略模式
感觉类似于桥接模式,只是具体区别还需要再研究
策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数,关系图如下
Strategy:策略(算法)抽象
ConcreteStrategy: 各种策略的具体实现
Context:策略的外部封装类,或者说策略的容器类,根据不同的策略执行不同的行为
,策略是由外部环境决定的。
优点:1提供了管理相关算法的办法,策略类的等级结构定义了一个算法或行为族,恰当的用继承
可以把公共的代码转移到父类里面避免重复代码。
2 提供了可以替换继承关系的办法,继承可以处理多种算法或行为,如果不用策略模式,那么使用算法或者行为的环境就可能会有一些子类。每个子类提供
一个不同的算法或行为,但是这样一来算法或行为使用者就和算法本身混在一起。决定
使用哪种算法或算法蔡旭哪一种行为的逻辑就和算法逻辑混在一起,从而不吭呢再独立演化。继承使动态改变算法或行为变成不可能。
3 避免使用多重条件转移语句
缺点:
1 客户端必须知道所有的策略类,并自行决定使用哪个策略类,这就意味着客户端必须理解这些算法区别,以便适时选择
恰当的算法类,换言之,策略模式只适用于客户端知道所有算法或行为的额情况
2策略模式会造成很多策略类,有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的。这样策略类实例可以被不同的客户端使用
换言之,可以使用享元模式来减少对象的使用
三个实例
实例一代码:
策略模式的决定权在用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此,策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可。
一个接口
public interface ICalculator {
public int calculate(String exp);
}
*****************************************************************************8
三个实现类:
/**
* 减法
*/
public class Minus extends AbstractCalculator implements ICalculator {
@Override
public int calculate(String exp) {
int arrayInt[] = split(exp,"-");
return arrayInt[0]-arrayInt[1];
}
}
*****************************************************************************8
/**
* 加法
*/
public class Plus extends AbstractCalculator implements ICalculator {
@Override
public int calculate(String exp) {
int arrayInt[] = split(exp,"\\+");
return arrayInt[0]+arrayInt[1];
}
}
*****************************************************************************8
/**
* 乘法
*/
public class Multiply extends AbstractCalculator implements ICalculator {
@Override
public int calculate(String exp) {
int arrayInt[] = split(exp,"\\*");
return arrayInt[0]*arrayInt[1];
}
}
*****************************************************************************8
//抽象类:辅助类
public abstract class AbstractCalculator {
public int[] split(String exp,String opt){
String array[] = exp.split(opt);
int arrayInt[] = new int[2];
arrayInt[0] = Integer.parseInt(array[0]);
arrayInt[1] = Integer.parseInt(array[1]);
return arrayInt;
}
}
*****************************************************************************8
/**
* 策略模式的决定权在用户,系统本身提供不同算法的实现,
*新增或者删除算法,对各种算法做封装。
*因此,策略模式多用在算法决策系统中,
*外部用户只需要决定用哪个算法即可。
*/
public class MainCLass {
public static void main(String[] args) {
String exp = "2+8";
ICalculator iCalculator = new Plus();
int result = iCalculator.calculate(exp);
System.out.println(result);
}
}
测试结果:
10
实例二:
public interface Strategy {
//加密算法
public void encrypt();
}
****************************************************
public class MdD5Strategy implements Strategy {
@Override
public void encrypt() {
System.out.println("使用MD5加密");
}
}
****************************************************
public class AESStrategy implements Strategy {
@Override
public void encrypt() {
System.out.println("使用AES加密");
}
}
****************************************************
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void encrypt() {
strategy.encrypt();
}
}
****************************************************
/**
* 根据传入不同的算法去执行不同的算法
*
*/
public class MainClass {
public static void main(String[] args) {
//具体实现从这里new出来传进去,然后执行具体实现的策略
Strategy strategy = new MdD5Strategy();
Context context = new Context(strategy);
context.encrypt();
Strategy strategy1 = new AESStrategy();
Context context1 = new Context(strategy1);
context1.encrypt();
}
}
****************************************************
测试结果:
使用MD5加密
使用AES加密
实例三:
public interface Strategy {
public double coust(double num);
}
*************************************************
/**
* 打八折
*
*/
public class StrategyA implements Strategy{
@Override
public double coust(double num) {
return num*0.8;
}
}
*************************************************
/**
* 满200减50活动
*/
public class StrategyB implements Strategy{
@Override
public double coust(double num) {
if(num >= 200){
return num -50;
}
return num;
}
}
*************************************************
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public double con(double num){
return strategy.coust(num);
}
}
*************************************************
测试结果:
160.0
/**
* 根据不同的价格执行不同的促销活动
*
*/
public class MainCLass {
public static void main(String[] args) {
Strategy strategy = new StrategyA();
//实际策略是从这里传进去的
Context context = new Context(strategy);
double result = context.con(200);
System.out.println(result);
}
}
总结:
在接口实现中具体实现策略,用接口父类调用,实际执行子类中的代码。
一切的设计模式都是类模式和对象模式,也就是继承或者持有对象引用来达到设计的目的。