提示

装饰器模式示例。@ermo

回到上一级

# 装饰器模式

装饰器模式主要有这么几部分组成

名称 描述
抽象组件类 被装饰的对象,只定义行为,具体的实现应该由子类完成
抽象实现 被装饰对象的具体实现,实现抽象组件类的抽象方法
抽象装饰类 抽象组件类的子类,内部维护抽象组件类的引用,并实现抽象组件类的抽象方法,具体增强行为应该由其子类实现
抽象装饰类实现 抽象装饰类的子类,用于增强抽象组件类的行为

来举一个简单例子,现在有一个订单审核功能,包括礼品订单和销售订单。

对于礼品订单不涉及金额,因此我们只需要在审核后给用户发送一条短信;

对于销售订单涉及金额,因此我们希望在订单审核前进行检查,并且在订单审核后要记录操作人信息理。

这个例子可以有很多种方法实现,本次只用装饰器来进行演示。

首先创建一个抽象组件类,并拥有审核订单的抽象方法。

public abstract class AbstractOrderAudit {

    /**
     * 订单审核
     * 
     * @param orderNo 订单编号
     */
    abstract void audit(String orderNo);
}

创建订单审核类的具体实现,该类实现了基本的审核功能。

public class OrderAuditImpl extends AbstractOrderAudit {
    
    @Override
    void audit(String orderNo) {
        System.out.println("订单审核成功:" + orderNo);
    }
}

创建抽象装饰类,实现订单审核抽象类,内部维护订单审核对象的引用,并且实现审核功能,供子类增强。

public class OrderAuditDecorator extends AbstractOrderAudit {

    private AbstractOrderAudit abstractOrderAudit;
    
    public OrderAuditDecorator(AbstractOrderAudit abstractOrderAudit) {
        this.abstractOrderAudit = abstractOrderAudit;
    }

    @Override
    void audit(String orderNo) {
        abstractOrderAudit.audit(orderNo);
    }
}

创建礼品订单装饰实现类,继承订单审核装饰类,对订单审核功能进行增强。

public class GiftOrderAudit extends OrderAuditDecorator {

    public GiftOrderAudit(AbstractOrderAudit abstractOrderAudit) {
        super(abstractOrderAudit);
    }

    @Override
    void audit(String orderNo) {
        super.audit(orderNo);
        // 审核后发送短信通知用户
        System.out.println("礼品订单,发送短信成功:" + orderNo);
    }
}

创建销售订单装饰实现类,继承订单审核装饰类,对订单审核功能进行增强。

public class SaleOrderAudit extends OrderAuditDecorator {

    public SaleOrderAudit(AbstractOrderAudit abstractOrderAudit) {
        super(abstractOrderAudit);
    }

    @Override
    void audit(String orderNo) {
        // 审核前进行订单校验
        System.out.println("销售订单校验成功:" + orderNo);
        super.audit(orderNo);
        // 审核后保存用户操作记录
        System.out.println("销售订单保存审核成功,保存用户操作记录:" + orderNo);
    }
}

编写测试代码。

    public static void main(String[] args) {
        // 基础订单审核
        AbstractOrderAudit orderAudit = new OrderAuditImpl();
        orderAudit.audit("123");
        System.out.println("--------------------华丽丽的分割线-----------------------");
        // 礼品订单的审核
        GiftOrderAudit giftOrderAudit = new GiftOrderAudit(orderAudit);
        giftOrderAudit.audit("456");
        System.out.println("--------------------华丽丽的分割线-----------------------");
        // 销售订单的审核
        SaleOrderAudit saleOrderAudit = new SaleOrderAudit(orderAudit);
        saleOrderAudit.audit("789");
    }

输出:

订单审核成功:123
--------------------华丽丽的分割线-----------------------
订单审核成功:456
礼品订单,发送短信成功:456
--------------------华丽丽的分割线-----------------------
销售订单校验成功:789
订单审核成功:789
销售订单保存审核成功,保存用户操作记录:789

可以看到三种类型的订单审核进行不同的输出内容,开发过程中,如果不想对历史代码进行侵入式的开发,使用装饰器模式可以很大程度的解耦合,并且可以进行各种个性化的增强。