商场中经常搞各种促销活动;例如:满200返50,打9折,会员8.8折,冲100送20等等。这些商业活动的背后商品价格的计算方式各不相同,种类繁复;着实让商场的收银员头痛不已。
为了应对类似的情况,我们的程序中或许要写很多的if…else进行分支判断造成代码臃肿、难以维护。此时,我们可用策略模式解救抓狂的商场收银员。
在此,概述策略模式。
Strategy Pattern:Define a family of algorithms,encapsulate each one and make them interchangeable.Strategy lets the algorithmvary independently from clients that use it。
策略模式:定义一系列的算法,把它们一个个封装起来,并且使他们可相互替换。本模式使得算法的变化可以独立于使用它的客户。
在此,介绍策略模式中的主要角色。
Context也叫做上下文角色,它 起承上启下封装作用;用于屏蔽高层模块对策略、 算法的直接访问,封装可能存在的变化。
策略或算法家族的抽象, 它通常被定义为接口或抽象类。该接口或抽象类中定义每个策略或算法必须具有的方法和属性。
实现抽象策略中的操作。
在此,以案例形式讲解策略模式。
CashStrategy为抽象类,代码如下:
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public abstract class CashStrategy {
public abstract double receiveCash(double money);
}

CashNormal类继承自CashStrategy;用于表示正常收费业务,代码如下:
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class CashNormal extends CashStrategy{
@Override
public double receiveCash(double money) {
return money;
}
}

CashDiscount类继承自CashStrategy;用于表示打折收费业务,代码如下:
package com.strategy01;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class CashDiscount extends CashStrategy{
private double discount=0;
public CashDiscount(double discount) {
this.discount = discount;
}
@Override
public double receiveCash(double money) {
return money*discount;
}
}

CashReturn类继承自CashStrategy;用于表示返现收费业务,代码如下:
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class CashReturn extends CashStrategy{
private double moneyThreshold;
private double moneyReturn;
public CashReturn(double moneyRaw, double moneyReturn) {
this.moneyThreshold = moneyRaw;
this.moneyReturn = moneyReturn;
}
@Override
public double receiveCash(double money) {
double result=money;
if(money>moneyThreshold) {
result = money - moneyReturn;
}
return result;
}
}

CashContext用于表示上下文,代码如下:
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class CashContext {
private CashStrategy cashStrategy;
public CashContext(CashStrategy cashStrategy) {
this.cashStrategy = cashStrategy;
}
public double charge(double money) {
return cashStrategy.receiveCash(money);
}
}

Test类为测试类,代码如下:
import java.util.Scanner;
/**
* 本文作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class Test {
public static void main(String[] args) {
Scanner scannner = new Scanner(System.in);
System.out.println("输入收费模式:");
String content = scannner.next();
CashContext cashContext = null;
switch (content) {
case "正常收费":
CashNormal cashNormal = new CashNormal();
cashContext = new CashContext(cashNormal);
break;
case "满200返50":
CashReturn cashReturn = new CashReturn(200, 50);
cashContext = new CashContext(cashReturn);
break;
case "打9折":
CashDiscount cashDiscount = new CashDiscount(0.9);
cashContext = new CashContext(cashDiscount);
break;
default:
System.out.println("信息有误,请重新输入");
break;
}
System.out.println("输入消费金额:");
double money = scannner.nextInt();
double result = cashContext.charge(money);
System.out.println("最终实际消费:" + result);
scannner.close();
}
}

