策略模式
1. 策略模式解决的问题
比如商场购物-打折 7,8,9折。虽然工厂模式也能实现,但是对于7,8,9折每个都对应着一个类,工厂类中也有各自new的分支对象。如果再增加比如满300返100的算法时,又要增加一个类,要求越多,增加的类越多;如果之前的算法不满足要求,则要进行修改,又要增加新的类。所以简单工厂能实现,但是不是最理想的。
面向对象的编程,并不是类越多越好,类的划分是为封装,但是分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。
策略模式
策略模式: 定义算法家族,分别封装起来,让他们之间可以互相替换,次模式让算法的变化,不会影响到使用算法的客户。
策略模式实现代码结构图
具体的代码如下
实现商场打折核心代码-策略结构
package shejimoshi.stratege;
/**
* 维护具体商场收费的策略实例,选择策略
*/
public class CashContext {
private CashSuper cashSuper;
//通过构造函数传入具体的收费策略
public CashContext(CashSuper cashSuper) {
this.cashSuper = cashSuper;
}
/**
* 根据收费策略的不同获得计算结果
* @param money
* @return
*/
public double getResult(double money){
return cashSuper.acceptCash(money);
}
}
//算法策略
现金收取的超类及具体的策略
package shejimoshi.stratege;
import java.awt.geom.Arc2D;
/**
*
*/
public abstract class CashSuper {
/**
* 现金收取超类的抽象方法,收取现金,参数为原价,返回为当前价
* @param money 原价
* @return 经过算法处理后的价格
*/
public abstract double acceptCash(double money);
}
/**
* 正常收费
*/
class CashNomal extends CashSuper{
@Override
public double acceptCash(double money) {
return money;
}
}
//打折收费
class CashRebate extends CashSuper{
private double moneyRebate = 0;
public CashRebate(String moneyRebate){
this.moneyRebate = Double.parseDouble(moneyRebate); //初始化折扣
}
@Override
public double acceptCash(double money) {
return money*moneyRebate;
}
}
//返利收费
class CashReturn extends CashSuper{
//返利收费,初始化必须要有返利条件和返回值,比如满300返100,300为moneyCondition,100为moneyReturn
private double moneyCondition = 0;
private double moneyReturn = 0;
public CashReturn(String moneyCondition, String moneyReturn) {
this.moneyCondition = Double.parseDouble(moneyCondition);
this.moneyReturn = Double.parseDouble(moneyReturn);
}
@Override
public double acceptCash(double money) {
//若大于等于阈值,则减去返利值
double result = money;
if (money>= moneyCondition){
result = money - Math.floor(money/moneyCondition)*moneyReturn;
}
return result;
}
}
//客户端调用类
可根据不同的策略调用不同的收费方法
package shejimoshi.stratege;
/**
*
*/
public class Client {
public static void main(String[] args) {
//CashSuper cashSuper = new CashRebate("0.8");
CashSuper cashSuper = new CashReturn("300","100");
CashContext context = new CashContext(cashSuper);
System.out.print(context.getResult(300));
}
}
总结:
策略模式是一种定义一系列算法的方法,从概念上看,所有的算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
**CashSuper **定义了一系列可重用的算法或者行为,继承有助于获取算法的公共功能。
另一优点:简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。