定义一系列的算法,把他们一个个封装起来,并且使他们可以相互替代。本模式使得算法可独立于使用它的客户而变化!
策略模式可以很好解决众多if问题
如以下:
package com.tao.YanMoDesignPattern.Strategy.notPattern;
/**
* @Author Mi_Tao
* @Date 2023/7/22
* @Description 价格管理,完成计算向客户所报价格的功能
* @Version 1.0
**/
public class Price {
public double quoto(double goodsPrice,String customerType){
if ("普通客户".equals(customerType)){
System.out.println("对于新客户或者普通客户,没有折扣!");
} else if ("老客户".equals(customerType)) {
System.out.println("对于老客户,一律折扣5%!");
return goodsPrice*(1-0.05);
} else if ("大客户".equals(customerType)) {
System.out.println("对于大客户,一律折扣10%!");
return goodsPrice*(1-0.1);
}
return 0.0;
}
}
先看一下标准的策略模式如何实现
上层接口,定义好行为
package com.tao.YanMoDesignPattern.Strategy.pattern;
/**
* @Author Mi_Tao
* @Date 2023/7/22
* @Description 策略,定义算法的接口
* @Version 1.0
**/
public interface Strategy {
public void algorithmInterface();
}
package com.tao.YanMoDesignPattern.Strategy.pattern;
/**
* @Author Mi_Tao
* @Date 2023/7/22
* @Description
* @Version 1.0
**/
public class ConcreteStartegbA implements Strategy{
@Override
public void algorithmInterface() {
// 具体的算法实现
}
}
package com.tao.YanMoDesignPattern.Strategy.pattern;
/**
* @Author Mi_Tao
* @Date 2023/7/22
* @Description
* @Version 1.0
**/
public class ConcreteStartegbB implements Strategy{
@Override
public void algorithmInterface() {
// 具体的算法实现
}
}
package com.tao.YanMoDesignPattern.Strategy.pattern;
/**
* @Author Mi_Tao
* @Date 2023/7/22
* @Description
* @Version 1.0
**/
public class ConcreteStartegbC implements Strategy{
@Override
public void algorithmInterface() {
// 具体的算法实现
}
}
核心实现
package com.tao.YanMoDesignPattern.Strategy.pattern;
/**
* @Author Mi_Tao
* @Date 2023/7/22
* @Description 上下文对象,通常会持有一个具体的策略对象
* @Version 1.0
**/
public class Context {
// 持有一个具体的策略对象
private Strategy strategy;
/**
* 上下文对客户端提供的操作接口,可以有参数和返回值
*/
public void contextInterface(){
// 通常会转调具体的策略对象进行算法运算
strategy.algorithmInterface();
}
}
package com.tao.YanMoDesignPattern.Strategy.caseChange;
/**
* @Author Mi_Tao
* @Date 2023/7/22
* @Description 策略,定义计算报价算法的接口
* @Version 1.0
**/
public interface Strategy {
/**
* 计算应报的价格
* @param goodsPrice
* @return 计算出来的,应给客户的报价
*/
public double calcPrice(double goodsPrice);
}
package com.tao.YanMoDesignPattern.Strategy.caseChange;
/**
* @Author Mi_Tao
* @Date 2023/7/22
* @Description
* @Version 1.0
**/
public class OldCusomerStategy implements Strategy {
@Override
public double calcPrice(double goodsPrice) {
System.out.println("老客户,5%折扣");
return goodsPrice*(1-0.05);
}
}
package com.tao.YanMoDesignPattern.Strategy.caseChange;
/**
* @Author Mi_Tao
* @Date 2023/7/22
* @Description
* @Version 1.0
**/
public class NormalCusomerStategy implements Strategy {
@Override
public double calcPrice(double goodsPrice) {
System.out.println("普通客户,没有折扣");
return goodsPrice;
}
}
package com.tao.YanMoDesignPattern.Strategy.caseChange;
/**
* @Author Mi_Tao
* @Date 2023/7/22
* @Description
* @Version 1.0
**/
public class LargeCusomerStategy implements Strategy {
@Override
public double calcPrice(double goodsPrice) {
System.out.println("大客户,10%折扣");
return goodsPrice*(1-0.1);
}
}
package com.tao.YanMoDesignPattern.Strategy.caseChange;
/**
* @Author Mi_Tao
* @Date 2023/7/22
* @Description 价格管理,主要完成计算向客户所报价格的功能
* @Version 1.0
**/
public class Price {
/**
* 持有一个具体的策略对象
*/
private Strategy strategy = null;
/**
* 构造方法,传入一个具体的策略对象
* @param strategy
*/
public Price(Strategy strategy) {
this.strategy = strategy;
}
/**
* 报价,计算客户的报价
* @param goodsPrice 商品销售原价
* @return 计算出来的,应该给客户的保教
*/
public double quote(double goodsPrice){
return this.strategy.calcPrice(goodsPrice);
}
}
测试类
package com.tao.YanMoDesignPattern.Strategy.caseChange;
/**
* @Author Mi_Tao
* @Date 2023/7/22
* @Description
* @Version 1.0
**/
public class Client {
public static void main(String[] args) {
// 1、选择并创建需要使用的策略对象
Strategy strategy = new LargeCusomerStategy();
// 2、创建上下文
Price ctx = new Price(strategy);
//3、计算报价
double quote = ctx.quote(1000);
System.out.println("向客户报价:"+quote);
}
}
策略模式的中心不是如何实现算法,而是如何组织,调用这些算法, 从而让程序结构更灵活,具有更好的维护性和扩展性。
经典的策略模式调用顺序
除此之外还可以解决:容错问题(上传文件是中途失败,下次要如何恢复到失败的问题。实现模板方法模式)
经典的策略模式UML图
策略模式的本质: 分离算法,选择实现
何时使用策略模式