1.意图:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。此模式使得算法可以独立于使用它们的客户而变化。
2.结构
Strategy(策略)定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法。
ConcreteStrategy(具体策略)以Strategy接口实现某具体算法。
Context(上下文)用一个ConcreteStrategy对象来配置:维护一个对Strategy对象的引用;可定义一个接口来让Strategy访问它的数据。
3.适用性:
许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
需要使用一个算法的不同变体。例如,定义一些反映不通空间的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时,可以使用策略模式。
算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,将相关的条件分支移入它们各自的Strategy类中,已代替这些条件语句。
4.常见案例:替换if else
代码案例一:
某软件公司预开发一款汽车竞速类游戏,需要模拟长轮胎和短轮胎刹车时在路面上留下的不同痕迹,并考虑后续能模拟更多中轮胎急刹车时的痕迹。线采用策略(Strategy)设计模式来实现该需求。
软件设计师考试2019年上半年下午题第6题
public class Strategy1 {
public static void main(String[] args) {
BrakeBehavior shortBrake = new ShortWheelBrake();
WheelCar car = new WheelCar(shortBrake);
car.brake();
BrakeBehavior longBrake = new LongWheelBrake();
car = new WheelCar(longBrake);
car.brake();
}
}
interface BrakeBehavior{
void stop();
}
class LongWheelBrake implements BrakeBehavior{
@Override
public void stop() {
System.out.println("模拟长轮胎刹车痕迹!");
}
}
class ShortWheelBrake implements BrakeBehavior{
@Override
public void stop() {
System.out.println("模拟短轮胎刹车痕迹!");
}
}
abstract class Car{
protected BrakeBehavior wheel;
public void brake(){
wheel.stop();
}
}
class WheelCar extends Car{
public WheelCar(BrakeBehavior behavior){
wheel = behavior;
}
}
运行结果:
代码案例二:
某大型购物中心预开发一套收银软件,要求其能够支持购物中心在不同时期推出的各种促销活动,如打折、返利(例如,满300减100)等等。现采用策略(Strategy)模式实现该要求。
软件设计师考试2015年下半年下午题第6题
public class Strategy2 {
public static void main(String[] args) {
CashContext cashContext = new CashContext(TYPE.NORMAL);
System.out.print("正常收费:");
System.out.println(cashContext.getResult(600));
cashContext = new CashContext(TYPE.CASH_RETORN);
System.out.print("满300返100:");
System.out.println(cashContext.getResult(600));
cashContext = new CashContext(TYPE.CASH_DISCOUNT);
System.out.print("打八折:");
System.out.println(cashContext.getResult(600));
}
}
enum TYPE{NORMAL,CASH_DISCOUNT,CASH_RETORN}
interface CashSuper{
double acceptCash(double money);
}
class CashNormal implements CashSuper{
@Override
public double acceptCash(double money) {
return money;
}
}
class CashDiscount implements CashSuper{
private double moneyDiscount;//折扣率
public CashDiscount(double moneyDiscount){
this.moneyDiscount = moneyDiscount;
}
@Override
public double acceptCash(double money) {
return money*moneyDiscount;
}
}
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;
}
}
class CashContext{
private CashSuper cs;
private TYPE t;
public CashContext(TYPE t){
switch (t){
case NORMAL://正常收费
cs = new CashNormal();
break;
case CASH_RETORN://满300返100
cs = new CashReturn(300,100);
break;
case CASH_DISCOUNT://打八折
cs = new CashDiscount(0.8);
break;
default:
break;
}
}
public double getResult(double money){
return cs.acceptCash(money);
}
}
运行结果: