• 首先在阐述需求之前对一些名词做点解释:
  1. 商户编号:有使用过POS机刷卡的同学,可能都会注意到POS签购单上有一个商户编号,这个编号有15位,前三位代表收单银行,第四位到第七位代表行政区划代码,第八位到第十一位代表商户类型代码及MCC码,最后四位就没什么特殊的了。
  2. 手续费:每一笔订单都会产生一笔手续费,从结算给商户的金额中扣取,和刷卡的客户无太多关系,一般按发卡行:收单机构:银联的比例为7:3:1或者8:1:1进行清分。
  3. 扣率:费率根据商户的类型(MCC)不同而不同,现在民生类的是0.38%的手续费,一般类是0.78%,餐娱类是1.25%。
  4. 订单:订单就是订单啦,应该没人不理解啦。
  • 然后描述需求:

现在针对每一笔订单,都会关联到一个商户;每一个商户关联一个固定商户编号;每个商户编号有不同的扣率。比如:1、按每笔收取固定手续费,没交易一笔订 单,收取5角;2、按百分比收取手续费,比如民生类商户按0.38%收取手续费,封顶金额16元;3、按不同交易金额区间收取不同的手续费,比如 0~5000收取每笔订单1元,5000~50000收取每笔订单5角,大于50000收取每笔订单2角;4、不同交易金额区间按不同百分比收取手续费等 等。

  • 具体设计不做赘述,直接上类图:


 策略接口StrategyCharge定义了一个计算手续费的方法,有四个实现类StrategyWithCount、StrategyWithCountByStage、StrategyWithRatio和StrategyWithRatioByStage,顾名思义,这四个类分别负责计算1每笔收取固定手续费、2每笔按不同金额区间收取不同手续费、3每笔按固定百分比收取手续费和4每笔按不同金额区间根据不同百分比收取手续的计算。

  • 所有类的代码如下:
package src.designpattern.strategy.ex2.model;/*** 扣率实体* * @author wusj* @time 2015年8月10日 上午11:23:06*/
public class DeductionRate {private String id;/*** 资金范围开始值*/private String rangeBottom;/*** 资金范围结束值*/private String rangeTop;/*** 扣率,(0,1)之间表示百分比,大于等于1表示每交易扣款金额(单位为分)*/private String ratio;/*** 最大值*/private String maximum;/*** 最小值*/private String minimum;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getRangeBottom() {return rangeBottom;}public void setRangeBottom(String rangeBottom) {this.rangeBottom = rangeBottom;}public String getRangeTop() {return rangeTop;}public void setRangeTop(String rangeTop) {this.rangeTop = rangeTop;}public String getRatio() {return ratio;}public void setRatio(String ratio) {this.ratio = ratio;}public String getMaximum() {return maximum;}public void setMaximum(String maximum) {this.maximum = maximum;}public String getMinimum() {return minimum;}public void setMinimum(String minimum) {this.minimum = minimum;}}
package src.designpattern.strategy.ex2.model;/*** 扣率和商户编码关联关系** @author wusj* @date 2015年8月10日 上午11:38:34*/
public class DeRateRelateMerCode {private String id;/*** 扣率ID*/private String decutionRateId;/*** 商户编号ID*/private String merchantCodeId;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getDecutionRateId() {return decutionRateId;}public void setDecutionRateId(String decutionRateId) {this.decutionRateId = decutionRateId;}public String getMerchantCodeId() {return merchantCodeId;}public void setMerchantCodeId(String merchantCodeId) {this.merchantCodeId = merchantCodeId;}}
package src.designpattern.strategy.ex2.model;/*** 商户号实体* * @author wusj* @time 2015年8月10日 上午11:23:20*/
public class MerchantCode {private String id;private String merchantName;/*** 扣率类型:*     1每笔收取固定手续费;*     2每笔按不同金额区间收取不同手续费;*  3每笔按固定百分比收取手续费;*     4每笔按不同金额区间根据不同百分比收取手续。*/private String rateType;/*** 手续费计算类*/private String chargeCalClass;private String others;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getMerchantName() {return merchantName;}public void setMerchantName(String merchantName) {this.merchantName = merchantName;}public String getRateType() {return rateType;}public void setRateType(String rateType) {this.rateType = rateType;}public String getChargeCalClass() {return chargeCalClass;}public void setChargeCalClass(String chargeCalClass) {this.chargeCalClass = chargeCalClass;}public String getOthers() {return others;}public void setOthers(String others) {this.others = others;}}
package src.designpattern.strategy.ex2.model;/*** 订单实体** @author wusj* @date 2015年8月10日 上午11:54:43*/
public class Order {private String id;/*** 交易金额(单位分)*/private String amount;/*** 商户编号ID*/private String merchantCodeId;/*** 手续费(单位分)*/private String charge;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getAmount() {return amount;}public void setAmount(String amount) {this.amount = amount;}public String getMerchantCodeId() {return merchantCodeId;}public void setMerchantCodeId(String merchantCodeId) {this.merchantCodeId = merchantCodeId;}public String getCharge() {return charge;}public void setCharge(String charge) {this.charge = charge;}}
package src.designpattern.strategy.ex2.service;import src.designpattern.strategy.ex2.model.Order;/*** 订单接口** @author wusj* @date 2015年8月10日 上午11:57:21*/
public interface OrderService {Order insert(Order order);void update(Order order);void delete(String orderId);void query(String orderId);
}
package src.designpattern.strategy.ex2.service;/*** 策略接口定义** @author wusj* @date 2015年8月10日 上午11:59:55*/
public interface StrategyCharge {/*** 计算手续费* * @param object* @return 返回手续费的字符串形式,单位为分*/String calcullateCharge(Object object);
}
package src.designpattern.strategy.ex2;import src.designpattern.strategy.ex2.service.StrategyCharge;/***** @author wusj* @date 2015年8月10日 上午11:59:24*/
public class ContextCharge {protected StrategyCharge strategyCharge;public String calculateCharge(Object object) {return strategyCharge.calcullateCharge(object);}
}
package src.designpattern.strategy.ex2;import src.designpattern.strategy.ex2.model.Order;
import src.designpattern.strategy.ex2.service.OrderService;
import src.designpattern.strategy.ex2.service.StrategyCharge;/*** 订单接口实现类** @author wusj* @date 2015年8月10日 下午1:19:32*/
public class OrderServiceImpl extends ContextCharge implements OrderService {public OrderServiceImpl(StrategyCharge strategyCharge) {this.strategyCharge = strategyCharge;}public Order insert(Order order) {String charge = this.calculateCharge(order);order.setCharge(charge);System.out.println("insert data");return order;}public void update(Order order) {System.out.println("update data.");}public void delete(String orderId) {System.out.println("delete data.");}public void query(String orderId) {System.out.println("query data.");}}
package src.designpattern.strategy.ex2;import java.util.ArrayList;
import java.util.List;import src.designpattern.strategy.ex2.model.DeductionRate;
import src.designpattern.strategy.ex2.model.Order;
import src.designpattern.strategy.ex2.service.StrategyCharge;/*** 计算每笔收取固定金额手续费的算法** @author wusj* @date 2015年8月10日 下午12:38:48*/
public class StrategyWithCount implements StrategyCharge {public String calcullateCharge(Object object) {// 计算订单的手续费,如果不是订单,抛出异常if (object instanceof Order) {Order order = (Order) object;String merchantCodeId = order.getMerchantCodeId();// 根据merchantCodeId查询DeRateRelateMerCode,再查询DeductionRateList<DeductionRate> rateList = query(merchantCodeId);DeductionRate rate = rateList.get(0);return rate.getRatio();} else {throw new UnsupportedOperationException();}}/*** 模拟查询* * @param merchantCodeId* @return*/private List<DeductionRate> query(String merchantCodeId) {// 需要实现DeductionRate rate = new DeductionRate();rate.setId("123");// 模拟每笔收取0.5元(即50fen)的手续费rate.setRatio("50");List<DeductionRate> list = new ArrayList<DeductionRate>(1);list.add(rate);return list;}
}
package src.designpattern.strategy.ex2;import src.designpattern.strategy.ex2.model.Order;
import src.designpattern.strategy.ex2.service.StrategyCharge;/*** 每笔按不同金额区间收取不同手续费的算法** @author wusj* @date 2015年8月10日 下午12:38:48*/
public class StrategyWithCountByStage implements StrategyCharge {public String calcullateCharge(Object object) {// 计算订单的手续费,如果不是订单,抛出异常if (object instanceof Order) {// 算法return "";} else {throw new UnsupportedOperationException();}}
}
package src.designpattern.strategy.ex2;import java.util.ArrayList;
import java.util.List;import src.designpattern.strategy.ex2.model.DeductionRate;
import src.designpattern.strategy.ex2.model.Order;
import src.designpattern.strategy.ex2.service.StrategyCharge;/*** 计算每笔收取“交易金额*固定百分比”的手续费算法** @author wusj* @date 2015年8月10日 下午12:38:48*/
public class StrategyWithRatio implements StrategyCharge {public String calcullateCharge(Object object) {// 计算订单的手续费,如果不是订单,抛出异常if (object instanceof Order) {Order order = (Order) object;String merchantCodeId = order.getMerchantCodeId();// 根据merchantCodeId查询DeRateRelateMerCode,再查询DeductionRateList<DeductionRate> rateList = query(merchantCodeId);DeductionRate rate = rateList.get(0);String ratio = rate.getRatio();String maximum = rate.getMaximum();String minimum = rate.getMinimum();Float ratioF = Float.parseFloat(ratio);Float maximumF = (maximum == null || "".equals(maximum)) ? -1f: Float.parseFloat(maximum);Float minimumF = (minimum == null || "".equals(minimum)) ? 0f: Float.parseFloat(minimum);Float amountF = Float.parseFloat(order.getAmount());Float chargeF = amountF * ratioF;chargeF = chargeF < minimumF ? minimumF : chargeF;chargeF = (maximumF != -1f && chargeF > maximumF) ? maximumF: chargeF;return String.valueOf(Math.round(chargeF));} else {throw new UnsupportedOperationException();}}/*** 模拟查询* * @param merchantCodeId* @return*/private List<DeductionRate> query(String merchantCodeId) {// 需要实现DeductionRate rate = new DeductionRate();rate.setId("123");// 模拟每笔手续交易金额*0.005,封顶手续费10元(1000分)rate.setRatio("0.005");rate.setMaximum("1000");List<DeductionRate> list = new ArrayList<DeductionRate>(1);list.add(rate);return list;}
}
package src.designpattern.strategy.ex2;import src.designpattern.strategy.ex2.model.Order;
import src.designpattern.strategy.ex2.service.StrategyCharge;/*** 每笔按不同金额区间根据不同百分比收取手续** @author wusj* @date 2015年8月10日 下午12:38:48*/
public class StrategyWithRatioByStage implements StrategyCharge {public String calcullateCharge(Object object) {// 计算订单的手续费,如果不是订单,抛出异常if (object instanceof Order) {// 算法return "";} else {throw new UnsupportedOperationException();}}
}
package src.designpattern.strategy.ex2;import src.designpattern.strategy.ex2.model.MerchantCode;
import src.designpattern.strategy.ex2.model.Order;
import src.designpattern.strategy.ex2.service.OrderService;
import src.designpattern.strategy.ex2.service.StrategyCharge;/*** 测试类** @author wusj* @date 2015年8月10日 下午1:24:23*/
public class MainTest {public static void main(String[] args) {String merchantCodeId = "159";Order order = new Order();order.setAmount("100");order.setId("123");order.setMerchantCodeId(merchantCodeId);try {OrderService orderService = new OrderServiceImpl(getContextCharge(merchantCodeId));Order temp = orderService.insert(order);System.out.println(temp.getCharge());} catch (Exception e) {e.printStackTrace();}}@SuppressWarnings("rawtypes")static StrategyCharge getContextCharge(String merchantCodeId)throws InstantiationException, IllegalAccessException,ClassNotFoundException {MerchantCode code = getMerchantCode(merchantCodeId);String className = code.getChargeCalClass();Class clazz = Class.forName(className);StrategyCharge charge = (StrategyCharge) clazz.newInstance();return charge;}static MerchantCode getMerchantCode(String merchantCodeId) {MerchantCode code = new MerchantCode();code.setId(merchantCodeId);code.setMerchantName("wusj");code.setRateType("1");// 测试每笔固定金额
//      code.setChargeCalClass("src.designpattern.strategy.ex2.StrategyWithCount");// 测试每笔固定比例,且最多可收取的手续费限额code.setChargeCalClass("src.designpattern.strategy.ex2.StrategyWithRatio");code.setOthers("others");return code;}
}

java设计模式之策略模式应用:订单手续费计算相关推荐

  1. Java设计模式之策略模式与状态模式

    一.策略模式定义 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们之间可以相互替换,策略模式可以在不影响客户端的情况下发生变化. 好了,定义看看就完了,我知道你很烦看定义. 二.策 ...

  2. Java设计模式之策略模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

  3. Java设计模式之策略模式+工厂模式+模板模式

    Java设计模式之策略模式+工厂模式+模板模式 1.策略模式+工厂模式+模板模式 个人的理解:实际开发工程中,一些业务很复杂的逻辑使用很多的 if 或者 if···else 语句,不利于维护和扩展,为 ...

  4. 【Java设计模式】策略模式

    (转载请注明出处:http://blog.csdn.net/buptgshengod) 1.背景知识 策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法.比如每 ...

  5. Java 设计模式之策略模式

    一.了解策略模式 1.1 什么是策略模式 策略模式 (Strategy Pattern) 是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换.此模式让算法的变化独立于使用算法的客 ...

  6. java解决策略膨胀_折腾Java设计模式之策略模式

    简介 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式.简单理解就是一组算法,可以互换,再简单点策略就是封装算法. 意图 定义一 ...

  7. 【设计模式】java设计模式之 -- 策略模式

    对于代码中总是会有需要变化的部分和需要固定不变的部分.对于需要变化的部分,一般可以采用继承的方式,让子类对父类的方法进行重写,以改变已有的行为:如果变化的部分并不是所有子类都必须要有的,那就可以采用接 ...

  8. Java设计模式之策略模式---写的比较有趣,推荐大家看看

    原文:http://blog.csdn.net/jason0539/article/details/45007553 背景 在软件开发中常常遇到这种情况,实现某一个功能有多种算法或者策略,我们可以根据 ...

  9. 《Java设计模式之策略模式》

    <二 >策略模式   相信很多人都玩过魔兽世界这款游戏,它里面的战士有三种姿态:防御.狂暴.战斗,那么在不同的场景下我们需要使用不通的姿态,比如当MT抗怪就需要使用防御姿态,战场需要使用战 ...

最新文章

  1. MIT Graph实践概述
  2. 利用VisualEsxtop工具图形化查看esxtop参数
  3. 1036: [ZJOI2008]树的统计Count
  4. Artlantis 2020中文版
  5. kibana操作elasticsearch:匹配查询(match)
  6. 在python中strip_python中strip()函数怎么用?
  7. P2048-[NOI2010]超级钢琴【RMQ,堆】
  8. tyvj/joyOI 1305-最大子序和【单调队列】
  9. MATLAB库函数polly2trellis(卷积码生成多项式转网格图描述)的实现过程详解
  10. vue watch 第一次不执行_Vue 实现前进刷新,后退不刷新的效果
  11. 后端开发如何设计数据库系列文章(二)设计大数据量表结构
  12. RabbitMQ学习笔记(二) 工作队列
  13. Windows下Node.js安装Canvas插件
  14. 玩水——西沙:在海的远处,水是那么蓝那么清
  15. java:利用数组实现将古诗词纵向输出
  16. android 支付宝私钥加密,支付宝支付密钥RSA1升级到RSA2
  17. xbox手柄映射_如何在Windows 10中重新映射Xbox One控制器的按钮
  18. MySQL 打开视图 1449_Mysql查询视图:ERROR 1449 (HY000)
  19. web前端技术有哪些,小白必看
  20. Handler---

热门文章

  1. 鸿蒙适配机型小米,华为鸿蒙适配机型公布 P50首发/小米10S才是真正至尊版
  2. 如何有效的清理c盘文件?真实有效
  3. 线程池:酷我音乐网站热歌排行榜里面的歌曲!
  4. 计算机语言phal语言,[6.1]-基于接口查询语言的SDK包
  5. python实现简单的ps色阶调整过程
  6. Centos7.4/RHEL7.4---Samba服务器的搭建
  7. 手机屏幕分辨率:物理分辨率和逻辑分辨率
  8. 微信公众号配置网页授权域名报错:无法访问xxx指向的web服务器或虚拟主机的目录
  9. 【OpenCV 4】图像像素的归一化
  10. 为什么我们要坚持写博客?