策略模式: 定义了算法家族,分别封装起来,让它们之间可以互相替换。
策略模式让算法独立于使用它的客户而独立变化,此模式让算法的变化,不会影响到使用算法的客户.
应用场景:
1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
3、 对客户(Duck)隐藏具体策略(算法)的实现细节,彼此完全独立。
优点:
1、 提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。
2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
缺点:
1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
/**
* 定义所有支持算法的公共接口,各种不同的算法以不同的方式实现这个接口
*
*/
public abstract class Strategy {
// 算法方法
public abstract void algorithmInterface();
}
/**
* 具体算法A,实现了Strategy定义的接口,提供具体的算法实现。
*
*/
public class ConcreteStrategyA extends Strategy{
@Override
public void algorithmInterface() {
System.out.println("具体算法A实现");
}
}
/**
* 具体算法B,实现了Strategy定义的接口,提供具体的算法实现。
*
*/
public class ConcreteStrategyB extends Strategy{
@Override
public void algorithmInterface() {
System.out.println("具体算法B实现");
}
}
/**
* 具体算法C,实现了Strategy定义的接口,提供具体的算法实现。
*
*/
public class ConcreteStrategyC extends Strategy{
@Override
public void algorithmInterface() {
System.out.println("具体算法C实现");
}
}
/**
* 上下文,根据具体的策略对象,调用其算法
*
*/
public class Context {
private Strategy strategy;
// 初始化时传入具体策略对象
public Context(Strategy strategy){
this.strategy = strategy;
}
// 根据具体的策略对象,调用其算法的方法
public void contextInterface(){
strategy.algorithmInterface();
}
}
public class Main {
public static void main(String[] args) {
// 由于实例化不同的策略,最终获得的结果就不尽相同
Context context = new Context(new ConcreteStrategyA());
context.contextInterface();
context = new Context(new ConcreteStrategyB());
context.contextInterface();
}
}
输出结果如下:
具体算法A实现
具体算法B实现
策略模式实例:(商场购物收费策略)
/**
* 现金收费抽象类
*
*/
public abstract class CashSuper {
public abstract double acceptCash(double money);
}
/**
* 正常收费子类,实现现金收费抽象类,提供具体的算法实现。
*
*/
public class CashNormal extends CashSuper{
@Override
public double acceptCash(double money) {
return money;
}
}
/**
* 返利收费子类,实现现金收费抽象类,提供具体的算法实现。
*
*/
public class CashReturn extends 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 = result - money/moneyCondition * moneyReturn;
}
return result;
}
}
/**
* 现金折扣类,实现现金收费抽象类,提供具体的算法实现。
*
*/
public class CashDiscount extends CashSuper{
// 折扣
private double discount;
public CashDiscount(double discount){
this.discount = discount;
}
@Override
public double acceptCash(double money) {
return money * discount;
}
}
/**
* 现金收费模式的枚举(包括正常收费,折扣,返利)
*
*/
public enum CashEnum {
Normal,Discount,Return;
}
/**
* 购物收费Context类(策略模式与简单工厂的结合)
*
*/
public class CashContext {
private CashSuper cashSuper;
// 策略模式与简单工厂的结合
public CashContext(CashEnum cashEnum){
switch(cashEnum){
case Normal:
this.cashSuper = new CashNormal();
break;
case Discount:
this.cashSuper = new CashDiscount(0.8);
break;
case Return:
this.cashSuper = new CashReturn(300,100);
break;
}
}
public double getResutl(double money){
double result = cashSuper.acceptCash(money);
return result;
}
}
public class Main {
public static void main(String[] args) {
// 正常收费
CashContext cashContext = new CashContext(CashEnum.Normal);
System.out.println(cashContext.getResutl(300));
// 折扣
cashContext = new CashContext(CashEnum.Discount);
System.out.println(cashContext.getResutl(300));
// 返利
cashContext = new CashContext(CashEnum.Return);
System.out.println(cashContext.getResutl(300));
}
}
输出结果如下:
300.0
240.0
200.0