`
无语的
  • 浏览: 12144 次
  • 性别: Icon_minigender_2
  • 来自: 成都
社区版块
存档分类
最新评论

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

阅读更多
  • 首先在阐述需求之前对一些名词做点解释:
  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,再查询DeductionRate
			List<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,再查询DeductionRate
			List<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;
	}
}
 

 

  • 大小: 43.8 KB
分享到:
评论

相关推荐

    Java 设计模式 策略模式

    策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在Java中,策略模式主要通过定义一系列的算法,并将每一个算法封装起来,使它们可以互相替换,让算法独立于使用它的客户而变化。 首先,策略模式的...

    Java设计模式综合应用场景

    【Java设计模式综合应用场景】 Java设计模式是一种在特定情境下解决软件设计问题的通用解决方案,它们代表了在软件设计过程中经过验证的、可重用的、面向对象的设计思想。在这个实验报告中,主要讨论了三种设计模式...

    《Java设计模式》刘伟 课后习题及模拟试题答案.rar

    《Java设计模式》是刘伟老师的一本经典教材,它深入浅出地讲解了软件设计中的重要概念——设计模式。设计模式是经验丰富的开发者在解决常见问题时总结出的通用解决方案,是软件开发中的智慧结晶。这本书的课后习题和...

    《java设计模式》课后习题模拟试题解答——刘伟.zip

    本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与应用,特别是针对刘伟教授的相关课程的课后习题及模拟试题的解答。 设计模式分为三大类:创建型、结构型和行为型模式。...

    java.设计模式大作业 薪资交付系统

    在Java编程领域,设计模式是一种解决常见问题的模板或最佳实践,它被广泛应用于构建可扩展、可维护的软件系统。在这个"薪资交付系统"的大作业中,我们可以预期会涉及多种设计模式,这些模式将帮助我们高效地组织代码...

    java 23种设计模式.zip

    设计模式主要分为三大类: 1.创建型模式:工厂模式、抽象...4.行为型模式:模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。

    java设计模式课程设计

    使用5种设计模式完成的一个点单系统,显示不同系列下的所有商品,点击选择冰度甜度之后添加到订单中,计算总金额,下单之后发送订单到门店的后厨制作商品。使用了抽象工厂模式、装饰模式、单例模式、代理模式、原型...

    《Java设计模式》课后习题参考答案-刘伟(20180723).pdf

    JDK中许多类和方法都使用了设计模式,这些模式的应用帮助实现了代码的高内聚、低耦合,提高了代码的可维护性和扩展性。下面介绍几种常见的设计模式及其在JDK中的应用实例: a) 抽象工厂模式(AbstractFactory) ...

    java设计模式(刘伟)

    ### Java设计模式(刘伟) #### 一、引言 在《Java设计模式》这本书中,作者刘伟全面地介绍了24种经典的设计模式,并通过丰富的案例和代码示例进行了详细的解析。本书不仅适合初学者作为入门教材,也适合有一定...

    策略模式在实际项目中的应用二

    策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在Java中,策略模式通过定义一系列的算法,并将每一个算法封装起来,使它们可以相互替换,让算法独立于使用它的客户而变化。这种模式通常用于处理多种...

    设计模式-Java语言中的应用

    设计模式通常分为三类:创建型模式(如工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式),结构型模式(如适配器模式、装饰器模式、代理模式、桥接模式、组合模式、外观模式、享元模式)以及行为型模式(如...

    Java设计模式教程-策略模式Java开发Java经验技

    在"Java设计模式教程——策略模式Java开发Java经验技巧共13页.pdf.zip"这份资料中,可能会详细讲解如何在实际项目中应用策略模式,包括但不限于以下内容: 1. 策略模式的基本结构和工作原理。 2. 如何定义策略接口...

    java23种设计模式+23个实例demo

    java23种设计模式+23个实例demo: 关于代码的几点说明: 1. 代码为根据个人对Design Pattern的学习理解写出, 2. 每个Pattern均是一个目录,其目录名即是Pattern的名字, 所有代码用JDeveloper 9i 和JBuilder 6.0编写...

    Java常用设计模式例子

    以JAVA为例,汇总了十几种常用的设计模式,包括了:单例模式、工厂模式、建造者模式、适配器模式、装饰器模式、外观模式、命令模式、观察者模式、状态模式、策略模式、模板方法模式等。仅供学习使用。 相关文章请看...

    java与模式,设计模式的应用

    Java与模式,设计模式的应用是软件工程中一个重要的主题,特别是在Java编程中。设计模式是对在软件设计中经常出现的问题及其解决方案的一种通用、可重用的描述。它们是经验丰富的开发者们智慧的结晶,旨在提高代码的...

    Java设计模式demo

    Java设计模式是软件工程中的一种最佳实践,它提供了一种在特定情况下解决常见问题的模板。这些模式来自于实际开发中的经验总结,可以帮助开发者更高效、更灵活地编写可复用和可维护的代码。在Java中,设计模式分为三...

    java web设计模式

    Java Web设计模式是一种在开发基于Java的Web应用程序时遵循的成熟解决方案,它们是解决常见问题的最佳实践。设计模式提供了一种标准的、可重用的方法来组织代码,提高可读性、可维护性和可扩展性。以下是Java Web...

    详解Java设计模式编程中的策略模式

    Java设计模式中的策略模式是一种行为设计模式,它允许在运行时选择不同的算法或策略,以适应不同的业务需求。策略模式的核心思想是将算法封装到独立的类中,这些类遵循一个公共接口,使得它们可以相互替换。这样做的...

Global site tag (gtag.js) - Google Analytics