设计模式总结-装饰者模式 (2)

2、营销券信息类:

/** * 营销券信息 * @author laoyeye.net * */ public class MarketCouponInfo implements Cloneable{ //券ID private int id; //券类型 private CouponTypeEnum couponType; //券金额 private Integer couponAmount; @Override public MarketCouponInfo clone(){ MarketCouponInfo couponInfo = null; try { couponInfo = (MarketCouponInfo)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return couponInfo; } }

3、产品信息类

/** * 产品信息 * @author laoyeye.net * */ public class FundProduct { /** * 产品code */ private String productCode; /** * 标的名称 */ private String name; /** * 标的单价 */ private Integer price; /** * 支持的营销券类型 */ private List<CouponTypeEnum> couponTypeList; }

4、支持的券枚举

/** * <p> * 优惠券类型 * </p> */ public enum CouponTypeEnum { RED_PACKET("红包"), COUPON("优惠券"); private String desc; CouponTypeEnum(String name) { this.desc = name; } public String getDesc() { return desc; } }

5、抽离出的基本需求
从第五步开始就真正进入了装饰模式的流程。
咱们这个需求最基本的需要就是计算客户实际金额,自然抽离出的基本需求是下面这个样子

/** * 基本需求,计算投资金额 * @author laoyeye.net * */ public interface IInvestDecorator { Integer calculateInvestAmount(Order order); }

6、具体对象,最基本的实现

/** * 原始投资金额计算 * @author laoyeye.net * */ public class BaseInvest implements IInvestDecorator { @Override public Integer calculateInvestAmount(Order order) { System.out.println("订单总金额为:" + order.getInvestCount() * order.getFundProduct().getPrice()); return order.getInvestCount() * order.getFundProduct().getPrice(); } }

7、基本装饰角色(类似于上文中的包工头)

/** * 投资金额计算的装饰类 * @author laoyeye.net * */ public abstract class BaseInvestDecorator implements IInvestDecorator{ private IInvestDecorator investDecorator; public BaseInvestDecorator(IInvestDecorator investDecorator) { this.investDecorator = investDecorator; } @Override public Integer calculateInvestAmount(Order order) { Integer payAmount = 0; if(investDecorator != null) { payAmount = investDecorator.calculateInvestAmount(order); } return payAmount; } }

8、接下来是两个具体实现角色
红包修饰类:

/** * 计算红包后的金额 * @author laoyeye.net * */ public class RedPacketDecorator extends BaseInvestDecorator{ public RedPacketDecorator(IInvestDecorator investDecorator) { super(investDecorator); } @Override public Integer calculateInvestAmount(Order order) { order.setInvestAmount(super.calculateInvestAmount(order)); return calculateCouponAmount(order); } private Integer calculateCouponAmount(Order order) { System.out.println("红包优惠金额:" + order.getRedPacketInfo().getCouponAmount()); return order.getInvestAmount() - order.getRedPacketInfo().getCouponAmount(); } }

优惠券修饰类:

/** * 计算优惠券后的金额 * @author laoyeye.net * */ public class CouponDecorator extends BaseInvestDecorator{ public CouponDecorator(IInvestDecorator investDecorator) { super(investDecorator); } @Override public Integer calculateInvestAmount(Order order) { order.setInvestAmount(super.calculateInvestAmount(order)); return calculateCouponAmount(order); } private Integer calculateCouponAmount(Order order) { System.out.println("优惠券金额:" + order.getCouponInfo().getCouponAmount()); return order.getInvestAmount() - order.getCouponInfo().getCouponAmount(); } }

9、工厂类
这是和上面装修的案例有稍许的不同,如果按照上述的方法来写的话,每次增加新的需求都要改动方法,这并不是工业级代码所想要的。
所以这里我们增加一个工厂类,当增加一个新的装饰需求,我们只需要修改工厂类,而不必动实际的代码即可。当然这部分实现方式还有很多,最核心的原则就是增加新的需求时,不需要频繁的改动核心代码。

/** * 营销活动工厂类 * @author laoyeye.net * */ public class MarketFactory { public static Integer getPayAmount(Order order) { //获取标的支持的营销类型 List<CouponTypeEnum> couponTypeList = order.getFundProduct().getCouponTypeList(); //初始化基本需求实现 IInvestDecorator decorator = new BaseInvest(); if(couponTypeList !=null && couponTypeList.size()>0) { for (CouponTypeEnum couponTypeEnum : couponTypeList) { decorator = decoratorType(couponTypeEnum, decorator); } } return decorator.calculateInvestAmount(order); } /** * 修饰方法的各种组合 * @param couponType * @param investDecorator * @return */ private static IInvestDecorator decoratorType(CouponTypeEnum couponType, IInvestDecorator investDecorator) { if(CouponTypeEnum.COUPON.equals(couponType)) { investDecorator = new CouponDecorator(investDecorator); }else if(CouponTypeEnum.RED_PACKET.equals(couponType)) { investDecorator = new RedPacketDecorator(investDecorator); } return investDecorator; } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwgwpz.html