策略模式

定义:它定义了算法家族,分别封装起来,让它们直接可以相互替换。策略模式让算法的变化不会影响到使用算法的客户。

解决问题:解决代码中由多个if...else或switch case 带来的不易维护。

使用场景:不同的类只是由于具体行为的不同。比如在业务场景中有不同时间下有不同逻辑处理等。

核心思想:所有算法都是完成相同的工作,只是实现不同,可以以相同的方式调用所有的算法,减少各种算法类与使用算法类之间的耦合。

优点:1、算法(变化点)自由切换 2、降低if...else等判断语句的复杂度 3、扩展性好

缺点:策略类增多。

结构图:

包含的角色:

抽象策略角色(Stratege):用接口或抽象类定义,给出所有具体策略类所需要的方法。

具体策略角色(ConcreteStrategy):实现具体算法。

环境角色(Context):持有抽象策略Strategy的引用,可以动态修改持有的具体策略ConcreteStragety,给客户调用;

使用场景及代码实现:

需求:商场促销,存在各种打折优惠的方式,比如:打8折、满300减50或正常收费。每次根据购物的金额和当前的优惠手段,计算出应付多少。

具体分析:不管是什么优惠,都是一样的调用。唯一的变化点就是优惠的具体实现不同,在优惠手段变化时,只需要替换这个变化点即可。

代码:

抽象策略方法:

public interface Stratege {
	public BigDecimal acceptAmount(BigDecimal amount);
}

具体策略方法:

public class StrategeNormal implements Stratege {//正常收费

	@Override
	public BigDecimal acceptAmount(BigDecimal amount) {
		
		return amount;
	}

}
public class StrategeRebate implements Stratege{//打折收费
	public BigDecimal rebate = null;
	public StrategeRebate(String rebate){
		this.rebate = new BigDecimal(rebate);
	}
	@Override
	public BigDecimal acceptAmount(BigDecimal amount) {
		return rebate.multiply(amount);
	}

}
public class StrategeReturn implements Stratege {//满300-50
	private BigDecimal moneyCondition = null;
	private BigDecimal moneyReturn = null;
	public StrategeReturn(String moneyCondition,String moneyReturn) {
		this.moneyCondition = new BigDecimal(moneyCondition);
		this.moneyReturn = new BigDecimal(moneyReturn);
	}
	@Override
	public BigDecimal acceptAmount(BigDecimal amount) {
		if(amount.compareTo(moneyCondition)>-1) {
			BigDecimal sBigDecimal = amount.divide(moneyCondition, 0,BigDecimal.ROUND_DOWN);
			return amount.subtract(sBigDecimal.multiply(moneyReturn));
		}else {
			return amount;
		}
	}

}

上下文:

public class Context {
	Stratege stratege;
	public Context(Stratege stratege) {
		this.stratege = stratege;
	}
	public BigDecimal  ContextInterface(BigDecimal amount) {//上下文接口,根据具体的策略,调用对应的方法。
		return stratege.acceptAmount(amount);
	}
}
//在此场景下,将简单工厂模式和策略模式进行结合,减少客户端的判断压力
public class Context {
	Stratege stratege;
	public Context(String type) {
		switch (type) {
		case "正常收费":
			stratege = new StrategeNormal();
			break;
		case "满300减50":
			stratege = new StrategeReturn("300","50");
			break;
		case "8折":
			stratege = new StrategeRebate("0.8");
			break;
		default:
			break;
		}
	}
	public BigDecimal  ContextInterface(BigDecimal amount) {
		return stratege.acceptAmount(amount);
	}
}

测试代码:

public class StrategeTest {

	public static void main(String[] args) {
		Context context =null;
		System.out.println("请输入优惠策略:");
		Scanner scanner = new Scanner(System.in);
		String stratege = scanner.nextLine();
		
		Context context2 = new Context(stratege);
		
		System.out.println("请输入金额:");
		Scanner scanner2 = new Scanner(System.in);
		String amount = scanner2.nextLine();
		
		BigDecimal result = context2.ContextInterface(new BigDecimal(amount));
		System.out.println(result);
	}

}

总结:策略封装了变化(算法)。在简单工厂模式下,客户端需要认识Operation和OperationFactory两个类,而在策略模式中,客户端只需要知道Context ,耦合度更低。

注:案例出自《大话设计模式》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值