策略这个词应该怎么理解,打个比方说,我们出门的时候会选择不同的出行方式,比如骑自行车、坐公交、坐火车、坐飞机、坐火箭等等,这些出行方式,每一种都是一个策略。
再比如我们去逛商场,商场现在正在搞活动,有打折的、有满减的、有返利的等等,其实不管商场如何进行促销,说到底都是一些算法,这些算法本身只是一种策略,并且这些算法是随时都可能互相替换的,比如针对同一件商品,今天打八折、明天满100减30,这些策略间是可以互换的。
策略模式是一种行为型设计模式,它允许在运行时选择算法的行为。在这个设计模式中,可以定义一系列的算法,将每种算法封装到单独的类中,并使它们可以相互替换。这样可以使算法的变化独立于使用算法的客户端。
在这个打折策略的例子中,我们使用了策略模式来实现不同的打折算法,包括正常收费、打折收费和返利收费。下面是策略模式的主要组成部分及其作用:
-
策略接口(CashSuper):定义了一个算法族的公共接口,其中包含了所有具体算法类所需的方法。在这个例子中,CashSuper接口定义了acceptCash方法,用于计算最终的收费金额。
-
具体策略类:每个具体策略类实现了策略接口,提供了特定的算法实现。在这个例子中,CashNormal、CashDiscount和CashReturn分别是具体策略类,分别表示了正常收费、打折收费和返利收费的算法实现。
-
上下文类(CashContext):上下文类持有一个策略对象的引用,并在运行时根据客户端的需要选择合适的策略。在这个例子中,CashContext类根据传入的打折类型选择对应的打折策略,并在客户端请求时调用选定策略的方法。
通过使用策略模式,我们可以方便地扩展和修改打折算法,而不必更改客户端的代码。例如,如果需要新增打折方式或修改现有的打折方式,只需创建新的具体策略类或修改现有的策略类,而不会影响到CashContext类或客户端的代码。这样的设计使得系统更加灵活和可维护。
另外,策略模式还有利于代码的复用,因为每个具体策略类都是独立的,可以在不同的上下文中重复使用。同时,由于算法的实现被封装到了具体策略类中,客户端可以专注于业务逻辑,而无需关注具体的算法实现细节。
总之,策略模式通过将算法封装成独立的策略类,并在运行时动态选择合适的策略,实现了算法的可插拔、可扩展和可维护的特性,是一种非常实用的设计模式。
package com.ss.qrcode.test;
public class CashContext {
private CashSuper cs;
/**
* 定义打折类型枚举
*/
public enum TYPE {
/**
* 正常收费
*/
NORMAL,
/**
* 打折收费
*/
CASH_DISCOUNT,
/**
* 返利收费
*/
CASH_RETURN
}
public CashContext(TYPE t) {
switch (t) {
case NORMAL:
cs = new CashNormal();
break;
// 假设打八折
case CASH_DISCOUNT:
cs = new CashDiscount(0.8);
break;
// 满300返100
case CASH_RETURN:
cs = new CashReturn(300, 100);
break;
default:
System.out.println("匹配不符 !");
}
}
/**
* 定义获取最终价格的方法
*/
public double getResult(double money) {
return cs.acceptCash(money);
}
public static void main(String[] args) {
// 输入原价,计算打折后的价格
// 正常收费
CashContext context1 = new CashContext(TYPE.NORMAL);
double result1 = context1.getResult(1000);
System.out.println("正常收费,结果:" + result1);
// 打折收费
CashContext context2 = new CashContext(CashContext.TYPE.CASH_DISCOUNT);
double result2 = context2.getResult(1000);// 八折
System.out.println("打折收费,结果:" + result2);
// 返利收费
CashContext context3 = new CashContext(TYPE.CASH_RETURN); // 满300返100
double result3 = context3.getResult(1000);
System.out.println("返利收费,结果:" + result3);
}
}
public class CashDiscount implements CashSuper{
// 折扣率
private double moneyDiscount;
public CashDiscount(double moneyDiscount){
this.moneyDiscount = moneyDiscount;
}
@Override
public double acceptCash(double money) {
return money*moneyDiscount;
}
}
public class CashNormal implements CashSuper{
@Override
public double acceptCash(double money) {
return money;
}
}
public class CashReturn implements CashSuper {
private double moneyCondition; // 满足返利条件的金额
private double moneyReturn; // 返利金额
public CashReturn(double moneyCondition, double moneyReturn) {
this.moneyCondition = moneyCondition;
this.moneyReturn = moneyReturn;
}
@Override
public double acceptCash(double money) {
double result = money;
if (money >= moneyCondition) {
// 计算返利金额
result = money - Math.floor(money / moneyCondition) * moneyReturn;
}
return result;
}
}