折扣计算,策略模式和装饰模式的具体应用。
package org.tang.zjnumall.strategy.discount; import java.math.BigDecimal; public abstract class AbstractDiscountStrategy { /** * 单价 */ protected BigDecimal price; /** * 数量 */ protected int copies; protected AbstractDiscountStrategy() { } /** * @param price 单价 * @param copies 数量 */ public AbstractDiscountStrategy(BigDecimal price, int copies) { this.price = price; this.copies = copies; } /** * 计算折扣额度 * * @return */ public abstract BigDecimal calculateDiscount(); }
package org.tang.zjnumall.strategy.discount; import java.math.BigDecimal; /** * 零折扣策略 * @author Tang * */ public class NoDiscountStrategy extends AbstractDiscountStrategy { @Override public BigDecimal calculateDiscount() { return new BigDecimal(0); } }
package org.tang.zjnumall.strategy.discount; import java.math.BigDecimal; /** * 单位固定折扣额策略 * @author Tang * */ public class FlatRateDiscountStrategy extends AbstractDiscountStrategy { /** * 单位折扣额 */ private BigDecimal discount; /** * * @param price 单价 * @param copies 数量 * @param discount 单位折扣额 */ public FlatRateDiscountStrategy(int copies, BigDecimal discount) { super.copies = copies; this.discount = discount; } @Override /** * 总折扣额 = 数量 * 单位折扣额 */ public BigDecimal calculateDiscount() { return new BigDecimal(copies).multiply(this.discount); } }
package org.tang.zjnumall.strategy.discount; import java.math.BigDecimal; /** * 折扣率策略 * @author Tang * */ public class PercentageDiscountStrategy extends AbstractDiscountStrategy { /** * 单位折扣率 */ private BigDecimal percent; /** * * @param price 单价 * @param copies 数量 * @param percent 单位折扣率 */ public PercentageDiscountStrategy(BigDecimal price, int copies, BigDecimal percent) { super(price, copies); this.percent = percent; } @Override /** * 总折扣额 = 单价 * 数量 * 单位折扣率 * */ public BigDecimal calculateDiscount() { return price.multiply(new BigDecimal(copies)).multiply(this.percent); } }
package org.tang.zjnumall.strategy.discount; import java.math.BigDecimal; /** * 限制折扣额策略 * @author Tang * */ public class RestrictedDiscountStrategy extends AbstractDiscountStrategy { /** * 折扣额度上限 */ private BigDecimal limit; private AbstractDiscountStrategy strategy; /** * * @param strategy 宿主策略 * @param limit 折扣限制额度 */ public RestrictedDiscountStrategy(AbstractDiscountStrategy strategy, BigDecimal limit) { this.limit = limit; this.strategy = strategy; } @Override /** * 当折扣额超过折扣限制额度时,总折扣额变为限制折扣额 */ public BigDecimal calculateDiscount() { BigDecimal preDiscount = this.strategy.calculateDiscount(); if (this.limit.doubleValue() > 0 && preDiscount.compareTo(this.limit) > 0) { return this.limit; } return preDiscount; } }
package org.tang.zjnumall.strategy.discount; import java.math.BigDecimal; public class DiscountCalculator { /** * 折扣策略 */ private AbstractDiscountStrategy strategy; public DiscountCalculator(){} /** * * @param strategy 具体折扣策略 */ public DiscountCalculator(AbstractDiscountStrategy strategy){ this.strategy = strategy; } public AbstractDiscountStrategy getStrategy() { return strategy; } public void setStrategy(AbstractDiscountStrategy strategy) { this.strategy = strategy; } public BigDecimal calculate(){ return null; } public static void main(String[] args){ BigDecimal price = new BigDecimal("99.99"); int copies = 9; BigDecimal percent = new BigDecimal("0.12"); BigDecimal discount = new BigDecimal("10"); BigDecimal limit = new BigDecimal("100"); AbstractDiscountStrategy noDiscount = new NoDiscountStrategy(); AbstractDiscountStrategy percentStrategy = new PercentageDiscountStrategy(price, copies, percent); AbstractDiscountStrategy flatRateStrategy = new FlatRateDiscountStrategy(copies, discount); AbstractDiscountStrategy restrictedStrategy = new RestrictedDiscountStrategy(percentStrategy, limit); System.out.println("折扣前总额:"+price.multiply(new BigDecimal(copies))); System.out.println("零折扣策略总折扣额:"+noDiscount.calculateDiscount()); System.out.println("折扣率策略总折扣额:"+percentStrategy.calculateDiscount()); System.out.println("固定折扣额策略总折扣额:"+flatRateStrategy.calculateDiscount()); System.out.println("限制折扣额策略总折扣额:"+restrictedStrategy.calculateDiscount()); } }