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、抽离出的基本需求
从第五步开始就真正进入了装饰模式的流程。
咱们这个需求最基本的需要就是计算客户实际金额,自然抽离出的基本需求是下面这个样子
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 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、工厂类
这是和上面装修的案例有稍许的不同,如果按照上述的方法来写的话,每次增加新的需求都要改动方法,这并不是工业级代码所想要的。
所以这里我们增加一个工厂类,当增加一个新的装饰需求,我们只需要修改工厂类,而不必动实际的代码即可。当然这部分实现方式还有很多,最核心的原则就是增加新的需求时,不需要频繁的改动核心代码。