策略模式概述:
策略模式(Pattern:Strategy)属于行为型模型,是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
策略模式包含的角色及其职责:
1. 上下文(环境)角色[Context]:持有一个策略类的引用,最终给客户端调用。内部维护一个Strategy的实例,需要使用ConcreteStrategy提供的算法,负责动态设置运行时Strategy具体的实现算法,负责跟Strategy之间的交互和数据传递。
2. 抽象策略角色[Strategy]:策略类,定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。
3. 具体策略类[ConcreteStrategy]:实现了Strategy定义的接口,包装了相关的算法和行为,提供具体的算法实现。
代码实现:
1.抽象策略角色。可以使用抽象类或者接口。
package StrategyPattern;
/**
* 现金收费抽象类
*/
public abstract class CashSuper {
//现金收取超类的抽象方法,收取现金,参数为原价,返回为当前价
public abstract double acceptCash(double money);
}
2.具体策略类。分别定义了三个类,正常收费类、打折收费类、返利收费类。
package StrategyPattern;
/**
* 正常收费子类,继承现金收费抽象类
*/
public class CashNormal extends CashSuper {
@Override
public double acceptCash(double money) {
//正常收费,返回原价
return money;
}
}
package StrategyPattern;
/**
* 打折收费子类,继承现金收费抽象类
*/
public class CashRebate extends CashSuper {
private double moneyRebate = 1;
public CashRebate(String moneyRebate) {
//打折收费,初始化时,必须输入折扣率,如八折,就是0.8
this.moneyRebate = Double.valueOf(moneyRebate);
}
@Override
public double acceptCash(double money) {
return money*moneyRebate;
}
}
package StrategyPattern;
/**
* 返利收费子类,继承现金收费抽象类
*/
public class CashReturn extends CashSuper {
private double moneyCondition = 0; //返利条件
private double moneyReturn = 0; //返利值
//返利收费,初始化时必须要输入返利条件和返利值,比如满300返100
public CashReturn(String moneyCondition, String moneyReturn) {
this.moneyCondition = Double.valueOf(moneyCondition);
this.moneyReturn = Double.valueOf(moneyReturn);
}
@Override
public double acceptCash(double money) {
if (money>=moneyCondition) {
//若大于返利条件,则需要减去返利值
return money-Math.floor(money/moneyCondition)*moneyReturn;
}
return money;
}
}
3.上下文角色:策略与简单工厂结合。
package StrategyPattern;
/**
* CashContext类
* 策略与简单工厂结合
*/
public class CashContext {
private CashSuper cs; //声明一个CashSuper对象
//通过构造方法,传入收费策略再生产具体的收费策略类
public CashContext(String rates) {
switch (rates) {
case "正常收费":
cs = new CashNormal();
break;
case "满1000减100":
cs = new CashReturn("1000", "100");
break;
case "打8折":
cs = new CashRebate("0.8");
break;
default:
break;
}
}
//根据收费策略的不同,获得计算结果
public double getResult(double money) {
return cs.acceptCash(money);
}
}
4.测试类
package StrategyPattern;
/**
* 客户端代码
*/
public class Test1 {
public static void main(String[] args) {
int number = 300; //商品数量
int price = 10; //商品单价
Normal(number, price); //正常收费
Rebate(number, price); //打折收费
Return(number, price); //满减收费
}
public static void Normal(int number, int price) {
CashContext ccNormal = new CashContext("正常收费");
double result = ccNormal.getResult(number*price);
System.out.println("正常收费:商品单价为:" + price + "元,商品数量为:" + number + "件,应付款:" + result + "元。");
}
public static void Rebate(int number, int price) {
CashContext ccRebate = new CashContext("打8折");
double result = ccRebate.getResult(number*price);
System.out.println("打折收费:商品单价为:" + price + "元,商品数量为:" + number + "件,应付款:" + result + "元。");
}
public static void Return(int number, int price) {
CashContext ccReturn = new CashContext("满1000减100");
double result = ccReturn.getResult(number*price);
System.out.println("打折收费:商品单价为:" + price + "元,商品数量为:" + number + "件,应付款:" + result + "元。");
}
}
5.测试结果
参考文档: