策略模式概念:它定义了算法家族,分别封装起来,让他们之前可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
业务场景:商场收银软件v1.0
需求1:做一个商场的收银软件,营业员根据客户所购买的商品的数量和单价,向客户收费。
代码实现:
package 策略模式;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double price = input.nextDouble();
int number = input.nextInt();
double sum = getSum(price,number);
System.out.println(sum);
}
private static double getSum(double price, int number) {
double result = 0.0;
result = price* number;
return result;
}
}
上述的代码很简单,相信大家都能看懂,但是上面的代码很难扩展,比如我又有一个需求:现在我要求商场对商品搞活动,所有的商品打八折。
package 策略模式;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double price = input.nextDouble();
int number = input.nextInt();
//打折
double zhe = input.nextDouble();
double sum = getSum(price,number,zhe);
System.out.println(sum);
}
private static double getSum(double price, int number,double zhe) {
double result = 0.0;
result = price* number*zhe;
return result;
}
}
又来一个需求3:商场活动力度要加大,需要有满三百返一百促销算法。是不是又要修改代码。我们可以用简单工厂模式来写
package 策略模式;
public interface CashSuper {
public double acceptCash(double money);//收取现金,参数为原价,返回当前价
}
package 策略模式;
/**
* 返利收费子类
* @author admin
*
*/
public class CashReturn implements CashSuper{
private double moneyCondition = 0;
private double moneyReturn=0;
public CashReturn(double moneyCondition,double moneyReturn){//返利收费,初始化时必须输入返利条件和返回利值
this.moneyCondition = moneyCondition;
this.moneyReturn = moneyReturn;
}
public double acceptCash(double money) {
double result = money;
if (money >= moneyCondition) {
result = money-(money/moneyCondition)*moneyReturn;
}
return result;
}
}
package 策略模式;
/***
* 打折收费子类
* @author admin
*
*/
public class CashRebate implements CashSuper{
private double moneyRebate=1;
public CashRebate(double moneyRebate){//打折收费初始化时必须输入折扣率
this.moneyRebate = moneyRebate;
}
public double acceptCash(double money) {
return money*moneyRebate;
}
}
package 策略模式;
/**
* 正常收费
* */
public class CashNormal implements CashSuper{
public double acceptCash(double money) {
return money;
}
}
package 策略模式;
/**
* 现金收费工厂
* @author admin
*
*/
public class CashFactory {
public static CashSuper createCashAccept(String type){
CashSuper result = null;
switch(type){
case "正常收费":
result = new CashNormal();
break;
case "满300返100":
result = new CashReturn(300, 100);
break;
case "打八折":
result = new CashRebate(0.8);
break;
}
return result;
}
}
是不是感觉上面的代码很清爽,确实,设计模式就是能给你带来清爽和飘柔的感觉。虽然简单工厂模式能解决上面的问题但是这个模式只是解决了对象的创建的问题,商场可能是经常性的改变打折额度和返利额度,每次维护和扩展收费的方式都需要去修改这个工厂,以至于代码需要重新编译和部署。这个不是最好的处理方式。策略模式可以很好的解决上面的问题:
package 策略模式;
/***
* 策略模式
* @author admin
*
*/
public class CashContext {
private CashSuper cashSuper;
public CashContext(CashSuper cashSuper){//通过构造方法传入具体的收费的策略
this.cashSuper = cashSuper;
}
/**策略模式与简单工厂结合*/
public CashContext(String type){//参数不是具体的收费策略对象而是一个字符串,表示收费类型
switch(type){
case "正常收费":
cashSuper = new CashNormal();
break;
case "满300返100":
cashSuper = new CashReturn(300, 100);
break;
case "打八折":
cashSuper = new CashRebate(0.8);
break;
}
}
public double GetResult(double money){//根据收费策略的不同获得计算的结果
return cashSuper.acceptCash(money);
}
}