装饰器模式能够实现为对象动态添加装修功能,它能从一个对象的外部来给对象添加功能,所以有非常灵活的扩展性,我们可以在对原来的代码毫无修改的前提下,为对象添加新功能。
除此之外,装饰器模式还能够实现对象的动态组合,借此我们可以很灵活地给动态组合的对象,匹配所需要的功能。
什么是装饰器模式?
装饰器模式包括了以下几个角色:接口、具体对象、装饰类、具体装饰类
接口定义了具体对象的一些实现方法;具体对象定义了一些初始化操作;
装饰类则是一个抽象类,主要用来初始化具体对象的一个类;其他的具体装饰类都继承了该抽象类。
一个简单的Demo
- 基础装饰接口:
/**
* 基础装饰接口.
*/
public interface IDecorator {
/**
* 装修方法.
*/
void decorate();
}
- 装饰基础类
/**
* 装饰基础类.
*
*/
public class Decorator implements IDecorator {
@Override
public void decorate() {
System.out.println("水电铺设、墙面粉刷。。。");
}
}
- 抽象类
/**
* 抽象类.
*
*/
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();
}
}
}
- 具体装饰类
/**
* 窗帘装饰类.
*
*/
public class CurtainDecorator extends BaseDecorator {
public CurtainDecorator(IDecorator decorator) {
super(decorator);
}
@Override
public void decorate() {
System.out.println("窗帘装饰。。。");
super.decorate();
}
}
- 测试
public static void main(String[] args) {
Decorator decorator = new Decorator();
CurtainDecorator curtainDecorator = new CurtainDecorator(decorator);
curtainDecorator.decorate();
}
执行结果:
窗帘装饰。。。
水电铺设、墙面粉刷。。。
优化电商系统中的商品价格策略
由于篇幅原因,只展示部分核心代码。
- 计算支付金额接口类
/**
* 计算支付金额接口类.
*
* @author liusj
* @date 2021/8/23
*/
public interface IBaseCount {
/**
* 商品支付金额.
*
* @param orderDetail
* @return
*/
BigDecimal countPayMoney(OrderDetail orderDetail);
}
- 支付基础实现类
/**
* 支付基础实现类.
*
* @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();
}
}
- 计算支付金额的抽象类(装饰类)
/**
* 计算支付金额的抽象类.
*
* @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;
}
}
- 计算使用优惠券后的金额 (具体装饰类)
/**
* 计算使用优惠券后的金额.
*
* @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();
}
}
- 计算使用红包后的金额
/**
* 计算使用红包后的金额.
*
* @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();
}
}
- 计算促销后的支付价格 (对象的动态组合)
/**
* 计算促销后的支付价格.
*
* @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;
}
}
网友评论