前言:策略模式是和简单工厂一起在几天前学的,今晚有空正好写下来
策略模式
策略模式是定义一组算法,将每一种算法都封装成共同接口的独立类中,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
优点:
缺点:
Strategy:抽象的策略(一个借口或抽象类)
ConcreteStrategy:具体的策略(实现了Strategy的算法类)
Context:策略上下文(策略模式的上下文类,持有Strategy类的引用,也可将策略的参数放置在上下文类中)

引用《大话设计模式》中的例子,商场购物有优惠,现有优惠方案:1、打折 2、满减,可能会有优惠方案:1、赠送积分
抽出父类策略类。
/**
* @ Author :fonxi
* @ Date :2019/5/10 2:56
* @ Description:策略类
*/
public interface Super {
Double count(Context ctx);
}
然后将每一种优惠方案当做一种算法,独立封装成具体策略类。
/**
* @ Author :fonxi
* @ Date :2019/5/10 2:56
* @ Description:具体策略-折扣类
*/
public class Discount implements Super{
@Override
public Double count(Context ctx) {
return ctx.getDiscountRate()*ctx.getMoney();
}
}
/**
* @ Author :fonxi
* @ Date :2019/5/10 2:56
* @ Description:具体策略-返利类
*/
public class Rebate implements Super{
@Override
public Double count(Context ctx) {
if(ctx.getMoney()>ctx.getRebateMoeny()){
return ctx.getMoney() - Math.floor(ctx.getMoney()/ctx.getRebateMoeny()) * ctx.getRebateValue();
}
return ctx.getMoney();
}
}
上下文中放置具体算法所需的参数,持有策略类的引用,并返回具体调用的策略算法。
/**
* @ Author :fonxi
* @ Date :2019/5/10 3:01
* @ Description:上下文
*/
@Data
public class Context {
//总金额
private Double money;
//折扣
private Double discountRate;
//到达额度 产生返利
private Double rebateMoeny;
//返利值
private Double rebateValue;
//持有一个策略对象
private Super superObject;
public Context(Double rebateMoeny,Double rebateValue,Double money,Double discountRate,Super superObject){
this.rebateMoeny = rebateMoeny;
this.rebateValue = rebateValue;
this.money = money;
this.discountRate = discountRate;
this.superObject = superObject;
}
public Double getResult(Context ctx){
return superObject.count(ctx);
}
}
在客户端,根据需求选择不同的策略,然后通过策略上下文得到不同的策略实现。
/**
* @ Author :fonxi
* @ Date :2019/5/10 3:10
* @ Description:客户端选择类
*/
public class Calculator {
public void print(){
Scanner s = new Scanner(System.in);
Context context = null;
//折扣
Double discountRate = null;
//到达额度 产生返利
Double rebateMoeny = null;
//返利值
Double rebateValue = null;
try {
System.out.println("请输入总金额");
Double money = s.nextDouble();
System.out.println("请选择折扣方式:1、打折2、返利");
String type = s.next();
if(type.equals("1")){
System.out.println("请输入折扣");
discountRate = s.nextDouble();
}
else if(type.equals("2")){
System.out.println("请输入满减额度");
rebateMoeny = s.nextDouble();
System.out.println("请输入满减值");
rebateValue = s.nextDouble();
}
Super superObject = null;
switch (type){
case "1":
superObject = new Discount();
break;
case "2":
superObject = new Rebate();
break;
default:
System.out.println("输入选择有误");
break;
}
context = new Context(rebateMoeny,rebateValue,money,discountRate,superObject);
System.out.println("结算金额是:"+context.getResult(context));
}catch (Exception e){
System.out.println("请输入有误"+e.getMessage());
}
}
}
策略模式使得每种算法都能够灵活的替换,并且在新增算法时不修改原有代码,不管是耦合性还是可扩展性都被大大的优化了,不过在客户端调用策略时会出现臃肿的选择,需要通过其他方式去优化。
原文:https://www.cnblogs.com/fonxi/p/10851004.html