1. 两个金额受影响:
1. IC卡固定余额=IC卡现有固定余额-交易金额/2
2. IC卡自由余额=IC卡现有自由金额-交易金额/2
1. 全部从自由金额上扣除
IC卡类
package com.peng.hb2;
/**
* @author kungfu~peng
* @data 2018年1月18日
* @description
*/
public class Card {
// IC卡号
private String cardNo = "";
// 卡内的固定交易金额
private int steadyMoney = 0;
// 卡内的自由金额
private int freeMoney = 0;
// getter/setter方法
public String getCardNo() {
return cardNo;
}
public void setCardNo(String cardNo) {
this.cardNo = cardNo;
}
public int getSteadyMoney() {
return steadyMoney;
}
public void setSteadyMoney(int steadyMoney) {
this.steadyMoney = steadyMoney;
}
public int getFreeMoney() {
return freeMoney;
}
public void setFreeMoney(int freeMoney) {
this.freeMoney = freeMoney;
}
}
交易类
package com.peng.hb2;
/**
* @author kungfu~peng
* @data 2018年1月18日
* @description
*/
public class Trade {
// 交易编号
private String tradeNo = "";
// 交易金额
private int amount = 0;
// getter/setter方法
public String getTradeNo() {
return tradeNo;
}
public void setTradeNo(String tradeNo) {
this.tradeNo = tradeNo;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
}
扣款策略接口
package com.peng.hb2;
/**
* @author kungfu~peng
* @data 2018年1月18日
* @description
*/
public interface IDeduction {
// 扣款,提供交易和卡信息,进行扣款,并返回扣款是否成功
public boolean exec(Card card, Trade trade);
}
扣款策略一
package com.peng.hb2;
/**
* @author kungfu~peng
* @data 2018年1月18日
* @description
*/
public class SteadyDeduction implements IDeduction {
// 固定性交易扣款
@Override
public boolean exec(Card card, Trade trade) {
// 固定金额和自由金额各扣除50%
int halfMoney = (int) Math.rint(trade.getAmount() / 2.0);
card.setFreeMoney(card.getFreeMoney() - halfMoney);
card.setSteadyMoney(card.getSteadyMoney() - halfMoney);
return true;
}
}
扣款策略二
package com.peng.hb2;
/**
* @author kungfu~peng
* @data 2018年1月18日
* @description
*/
public class FreeDeduction implements IDeduction {
// 自由扣款
@Override
public boolean exec(Card card, Trade trade) {
// 直接从自由余额中扣除
card.setFreeMoney(card.getFreeMoney() - trade.getAmount());
return true;
}
}
扣款策略的封装
package com.peng.hb2;
/**
* @author kungfu~peng
* @data 2018年1月18日
* @description
*/
public class DeductionContext {
// 扣款策略
private IDeduction deduction = null;
// 构造函数传递策略
public DeductionContext(IDeduction deduction) {
super();
this.deduction = deduction;
}
// 进行扣款
public boolean exec(Card card, Trade trade) {
return this.deduction.exec(card, trade);
}
}
策略枚举
package com.peng.hb2;
/**
* @author kungfu~peng
* @data 2018年1月18日
* @description 策略枚举
*/
public enum StrategyMan {
SteadyDeduction("com.peng.hb2.SteadyDeduction"), FreeDeduction(
"com.peng.hb2.FreeDeduction");
String value = "";
private StrategyMan(String _value) {
this.value = _value;
}
public String getValue() {
return value;
}
}
策略工厂
package com.peng.hb2;
/**
* @author kungfu~peng
* @data 2018年1月18日
* @description
*/
public class StrategyFactory {
// 策略工厂
public static IDeduction getDeduction(StrategyMan strategy) {
IDeduction deduction = null;
try {
deduction = (IDeduction) Class.forName(strategy.getValue())
.newInstance();
} catch (Exception e) {
System.err.println(e.getMessage());
}
return deduction;
}
}
扣款模块的封装
package com.peng.hb2;
/**
* @author kungfu~peng
* @data 2018年1月18日
* @description 扣款模块封装
*/
public class DeductionFacade {
// 对外公布的扣款信息
public static Card deduct(Card card, Trade trade) {
// 获得消费策略
StrategyMan reg = gerDeductionType(trade);
// 初始化一个消费策略对象
IDeduction deduction = StrategyFactory.getDeduction(reg);
// 产生一个策略的上下文
DeductionContext context = new DeductionContext(deduction);
// 进行扣款处理
context.exec(card, trade);
// 返回扣款处理完毕的数据
return card;
}
// 获得对应商户的消费策略
private static StrategyMan gerDeductionType(Trade trade) {
// 模拟操作
if (trade.getTradeNo().contains("peng")) {
return StrategyMan.FreeDeduction;
}else{
return StrategyMan.SteadyDeduction;
}
}
}
场景类
package com.peng.hb2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author kungfu~peng
* @data 2018年1月18日
* @description
*/
public class Client {
// 模拟交易
public static void main(String[] args) {
// 初始化一张IC卡
Card card = initIC();
// 显示一下卡的信息
System.out.println("=======初始化信息========");
showCard(card);
// 是否停止运行的标志
boolean flag = true;
while (flag) {
Trade trade = createTrade();
DeductionFacade.deduct(card, trade);
// 交易成功,打印出成功处理信息
System.out.println("\n========交易凭证===========");
System.out.println(trade.getTradeNo() + "交易成功!");
System.out.println("本次发生的交易金额为:" + trade.getAmount() * 100 / 100.0
+ "元");
// 展示一下卡内的信息
showCard(card);
System.out.println("是否需要退出?(Y/N)");
if (getInput().equalsIgnoreCase("y")) {
flag = false;
}
}
}
/**
* 获取输入
*
* @throws IOException
*/
private static String getInput() {
String str = "";
try {
str = (new BufferedReader(new InputStreamReader(System.in)))
.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
/**
* 产生一个交易
*/
private static Trade createTrade() {
Trade trade = new Trade();
System.out.println("请输入交易编码:");
trade.setTradeNo(getInput());
System.err.println("请输入交易金额:");
trade.setAmount(Integer.parseInt(getInput()));
// 返回交易
return trade;
}
/**
* 功能:打印Card的信息
*/
private static void showCard(Card card) {
System.out.println("IC卡编号:" + card.getCardNo());
System.out.println("固定类型余额:" + card.getSteadyMoney() * 100 / 100.0
+ "元");
System.out.println("自由类型余额:" + card.getFreeMoney() * 100 / 100.0 + "元");
}
/**
* 功能:初始化一个Card
*/
private static Card initIC() {
Card card = new Card();
card.setCardNo("1104561811");
card.setFreeMoney(100000);
card.setSteadyMoney(800000);
return card;
}
}
执行结果
=======初始化信息========
IC卡编号:1104561811
固定类型余额:800000.0元
自由类型余额:100000.0元
请输入交易编码:
666
请输入交易金额:
123
========交易凭证===========
666交易成功!
本次发生的交易金额为:123.0元
IC卡编号:1104561811
固定类型余额:800000.0元
自由类型余额:99877.0元
是否需要退出?(Y/N)
n
请输入交易编码:
888
请输入交易金额:
345
========交易凭证===========
888交易成功!
本次发生的交易金额为:345.0元
IC卡编号:1104561811
固定类型余额:800000.0元
自由类型余额:99532.0元
是否需要退出?(Y/N)
y