美文网首页
【设计模式】- 装饰器模式

【设计模式】- 装饰器模式

作者: lconcise | 来源:发表于2021-09-18 18:38 被阅读0次

    装饰器模式能够实现为对象动态添加装修功能,它能从一个对象的外部来给对象添加功能,所以有非常灵活的扩展性,我们可以在对原来的代码毫无修改的前提下,为对象添加新功能

    除此之外,装饰器模式还能够实现对象的动态组合,借此我们可以很灵活地给动态组合的对象,匹配所需要的功能。

    什么是装饰器模式?

    装饰器模式包括了以下几个角色:接口、具体对象、装饰类、具体装饰类
    接口定义了具体对象的一些实现方法;具体对象定义了一些初始化操作;
    装饰类则是一个抽象类,主要用来初始化具体对象的一个类;其他的具体装饰类都继承了该抽象类。

    一个简单的Demo

    1. 基础装饰接口:
    /**
     * 基础装饰接口.
     */
    public interface IDecorator {
    
        /**
         * 装修方法.
         */
        void decorate();
    }
    
    1. 装饰基础类
    /**
     * 装饰基础类.
     *
     */
    public class Decorator implements IDecorator {
    
        @Override
        public void decorate() {
            System.out.println("水电铺设、墙面粉刷。。。");
        }
    }
    
    1. 抽象类
    /**
     * 抽象类.
     *
     */
    public abstract class BaseDecorator implements IDecorator {
    
        private IDecorator decorator;
    
        public BaseDecorator(IDecorator decorator) {
            this.decorator = decorator;
        }
    
        @Override
        public void decorate() {
            if (decorator != null) {
                decorator.decorate();
            }
        }
    }
    
    1. 具体装饰类
    /**
     * 窗帘装饰类.
     *
     */
    public class CurtainDecorator extends BaseDecorator {
    
        public CurtainDecorator(IDecorator decorator) {
            super(decorator);
        }
    
        @Override
        public void decorate() {
            System.out.println("窗帘装饰。。。");
            super.decorate();
        }
    }
    
    1. 测试
        public static void main(String[] args) {
            Decorator decorator = new Decorator();
    
            CurtainDecorator curtainDecorator = new CurtainDecorator(decorator);
            curtainDecorator.decorate();
        }
    

    执行结果:

    窗帘装饰。。。
    水电铺设、墙面粉刷。。。
    

    优化电商系统中的商品价格策略

    由于篇幅原因,只展示部分核心代码。

    1. 计算支付金额接口类
    /**
     * 计算支付金额接口类.
     *
     * @author liusj
     * @date 2021/8/23
     */
    public interface IBaseCount {
    
        /**
         * 商品支付金额.
         *
         * @param orderDetail
         * @return
         */
        BigDecimal countPayMoney(OrderDetail orderDetail);
    }
    
    1. 支付基础实现类
    /**
     * 支付基础实现类.
     *
     * @author liusj
     * @date 2021/8/23
     */
    public class BaseCount implements IBaseCount {
    
        @Override
        public BigDecimal  countPayMoney(OrderDetail orderDetail) {
            orderDetail.setPayMoney(orderDetail.getMerchandise().getPrice());
            System.out.println("商品元单价金额为:" + orderDetail.getPayMoney());
            return orderDetail.getPayMoney();
        }
    }
    
    1. 计算支付金额的抽象类(装饰类)
    /**
     * 计算支付金额的抽象类.
     *
     * @author liusj
     * @date 2021/8/23
     */
    @Data
    public abstract class BaseCountDecorator implements IBaseCount {
    
        private IBaseCount count;
    
        public BaseCountDecorator(IBaseCount count) {
            this.count = count;
        }
    
        @Override
        public BigDecimal countPayMoney(OrderDetail orderDetail) {
            BigDecimal payTotalMoney = new BigDecimal(0);
            if (count != null) {
                payTotalMoney = count.countPayMoney(orderDetail);
            }
            return payTotalMoney;
        }
    }
    
    1. 计算使用优惠券后的金额 (具体装饰类)
    /**
     * 计算使用优惠券后的金额.
     *
     * @author liusj
     * @date 2021/8/23
     */
    public class CouponDecorator extends BaseCountDecorator {
    
        public CouponDecorator(IBaseCount count) {
            super(count);
        }
    
        @Override
        public BigDecimal countPayMoney(OrderDetail orderDetail) {
            BigDecimal payTotalMoney = new BigDecimal(0);
            super.countPayMoney(orderDetail);
            payTotalMoney = countCouponPayMoney(orderDetail);
            return payTotalMoney;
        }
    
        private BigDecimal countCouponPayMoney(OrderDetail orderDetail) {
            BigDecimal coupon = orderDetail.getMerchandise()
                    .getSupportPromotions()
                    .get(PromotionType.COUPON)
                    .getUserCoupon()
                    .getCoupon();
            System.out.println("优惠金额:" + coupon);
    
            orderDetail.setPayMoney(orderDetail.getPayMoney().subtract(coupon));
    
            return orderDetail.getPayMoney();
        }
    }
    
    1. 计算使用红包后的金额
    /**
     * 计算使用红包后的金额.
     *
     * @author liusj
     * @date 2021/8/23
     */
    public class RedPacketDecorator extends BaseCountDecorator {
    
        public RedPacketDecorator(IBaseCount count) {
            super(count);
        }
    
        @Override
        public BigDecimal countPayMoney(OrderDetail orderDetail) {
            BigDecimal payTotalMoney = new BigDecimal(0);
            super.countPayMoney(orderDetail);
            payTotalMoney = countReadPacketMoney(orderDetail);
            return payTotalMoney;
        }
    
        private BigDecimal countReadPacketMoney(OrderDetail orderDetail) {
            BigDecimal redPacket = orderDetail.getMerchandise()
                    .getSupportPromotions()
                    .get(PromotionType.READ_PACKED)
                    .getUserRedPacket()
                    .getRedPacket();
            System.out.println("红包优惠金额:" + redPacket);
    
            orderDetail.setPayMoney(orderDetail.getPayMoney().subtract(redPacket));
    
            return orderDetail.getPayMoney();
        }
    }
    
    1. 计算促销后的支付价格 (对象的动态组合)
    /**
     * 计算促销后的支付价格.
     *
     * @author liusj
     * @date 2021/8/23
     */
    public class PromotionFactory {
    
        public static BigDecimal getPayMoney(OrderDetail orderDetail) {
            // 获取商品设定的促销类型
            Map<PromotionType, SupportPromotions> supportPromotions = orderDetail.getMerchandise().getSupportPromotions();
    
            // 初始化计算类
            IBaseCount baseCount = new BaseCount();
            // 遍历设置的促销类型,通过装饰器组合促销类型
            if (supportPromotions != null && supportPromotions.size() > 0) {
                for (PromotionType promotionType : supportPromotions.keySet()) {
                    baseCount = promotion(supportPromotions.get(promotionType), baseCount);
                }
            }
            return baseCount.countPayMoney(orderDetail);
        }
    
        /**
         * 组合促销类型.
         *
         * @param supportPromotions
         * @param baseCount
         * @return
         */
        private static IBaseCount promotion(SupportPromotions supportPromotions, IBaseCount baseCount) {
            if (supportPromotions.getPromotionType() == PromotionType.COUPON) {
                baseCount = new CouponDecorator(baseCount);
            } else if (supportPromotions.getPromotionType() == PromotionType.READ_PACKED) {
                baseCount = new RedPacketDecorator(baseCount);
            }
            return baseCount;
        }
    }
    

    相关文章

      网友评论

          本文标题:【设计模式】- 装饰器模式

          本文链接:https://www.haomeiwen.com/subject/jdkiwltx.html