综合性模式设计

(1)一张IC卡绑定两个账户:固定账户和自由账户。

(2)两套交易扣款策略: 

固定消费场所下的消费是从IC卡中固定账户金额中扣除,当固定金额不够时,差额再从自由账户中扣除。

非固定消费场所下的消费都从IC卡中自由账户金额中扣除。

(3)IC卡交易扣款系统使用了以下几个模式 :

策略模式:负责对扣款策略进行封装,保证两个策略可以自由切换,也便于对扣款策略进行扩展。例如,增加一个新的扣款策略,只需三步就可以完成,先定义一个实现IDeduction接口的策略类,再在策略枚举StrategyMan中增加一个枚举项,最后在封装类DeductionFacade的getDeductionType()方法中增加对扣款策略的利用。

工厂方法模式:由工厂方法模式直接产生一个具体策略对象,使其他模块无需依赖具体的策略。

外观模式:负责对复杂的扣款系统进行封装,避免高层模块深入子系统内部细节,同时提高系统的高内聚、低耦合的特性。

package 交易;

//IC卡类

public class Card {

private String cardNo="";

private int steadyMoney=0;

private int freeMoney=0;

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 交易;

//交易信息Trade类

public class Trade {

private String tradeNo="";

private int amount=0;

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 交易;

//扣款接口,策略模式:两种策略:固定扣款和自由扣款

public interface IDeduction {

//扣款,提供交易和卡信息,进行扣款,并返回扣款是否成功

boolean exec(Card card,Trade trade);

}

package 交易;

public class SteadyDeduction implements IDeduction {

@Override

public boolean exec(Card card, Trade trade) {

int useMoney1=trade.getAmount();

if(useMoney1>card.getSteadyMoney()){

int useMoney2=(card.getSteadyMoney()-useMoney1);

card.setSteadyMoney(card.getSteadyMoney()-card.getSteadyMoney());

card.setFreeMoney(card.getFreeMoney()+useMoney2);

}

else{

card.setSteadyMoney(card.getSteadyMoney()-useMoney1);

}

return true;

}

}

package 交易;

public class FreeDeduction implements IDeduction {

@Override

public boolean exec(Card card, Trade trade) {

card.setFreeMoney(card.getFreeMoney()-trade.getAmount());

return true;

}

}

package 交易;

//封装角色,策略上下文

public class DeductionContext {

private IDeduction deduction=null;

public DeductionContext(IDeduction deduction){

this.deduction=deduction;

}

public boolean exec(Card card,Trade trade){

return this.deduction.exec(card, trade);

}

}

package 交易;

//负责对具体策略的映射,具体策略都在这里登记,然后提供给工厂方法模式。

public enum StrategyMan{

SteadyDeduction("交易.SteadyDeduction"),

FreeDeduction("交易.FreeDeduction");

String value="";

private StrategyMan(String value){

this.value=value;

}

public String getValue(){

return value;

}

}

package 交易;

//策略工厂,根据策略管理类的枚举创建一个策略对象

public class StrategyFactory {

public static IDeduction getDeduction(StrategyMan strategy){

IDeduction deduction=null;

try{

deduction=(IDeduction)Class.forName(strategy.getValue()).newInstance();//newInstance方法在内存中生成一个实例

}

catch(InstantiationException|IllegalAccessException|ClassNotFoundException e){

e.printStackTrace();

}

return deduction;

}

}

package 交易;

public class DeductionFacade {

//对外公布的扣款信息

public static Card deduct(Card card,Trade trade){

//获得消费策略

StrategyMan reg=getDeductionType(trade);

//初始化一个消费策略对象

IDeduction deduction=StrategyFactory.getDeduction(reg);

//产生一个策略上下文

DeductionContext context=new DeductionContext(deduction);

//进行扣款处理

context.exec(card, trade);

//返回扣款处理完毕后的数据

return card;

}

//获得对应的商户消费策略

private static StrategyMan getDeductionType(Trade trade) {

if(trade.getTradeNo().contains("abc")){

return StrategyMan.FreeDeduction;

}else{

return StrategyMan.SteadyDeduction;

}

}

}

package 交易;

import java.io.IOException;

import java.util.Scanner;

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.print("\n是否需要退出?(Y/N)");

if(getInput().equalsIgnoreCase("y")){

flag=false;//退出

}

}

}

private static String getInput() {

Scanner input=new Scanner(System.in);

String str=input.next();

return str;

}

private static Trade createTrade() {

Trade trade=new Trade();

System.out.print("请输入交易编号:");

trade.setTradeNo(getInput());

System.out.print("请输入交易金额:");

trade.setAmount(Integer.parseInt(getInput()));

return trade;

}

private static void showCard(Card card) {

System.out.println("IC卡编号:"+card.getCardNo());

System.out.println("固定类型金额:"+card.getSteadyMoney());

System.out.println("自由类型金额:"+card.getFreeMoney());

}

private static Card initIC() {

Card card=new Card();

card.setCardNo("1100010001000");

card.setSteadyMoney(10000);

card.setFreeMoney(80000);

return card;

}

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值