装饰器模式

装饰器模式(Decorator Pattern)

定义

也叫包装模式 (Wrapper Pattern)

是指在不改变原有对象的基础上,将功能附加到对象上,提供了比继承更有弹性的替代方案。

属于结构型模式。

适用场景

  1. 适用于扩展一个类的功能或给一个类添加附加职责。
  2. 动态的给一个对象添加功能,这些功能可以再动态的撤销。
  3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,使用继承关系将变得非常复杂。

标准示例

Component 是一个最顶层的抽象组件。

其他都是Component的子类。

ConcreteComponent 是一个具体的组件,是默认的标配。

Decorator 是一个抽象的装饰器,让用户可以对其扩展定制。

ConcreteDecoratorA、ConcreteDecoratorB 就是两个具体的装饰类。

上述类图中具体代码如下:
Component

java 复制代码
public abstract class Component {
    public abstract void operation();
}

Decorator

java 复制代码
public abstract class Decorator extends Component{
    //持有组件对象
    protected Component component;

    /**
     * 构造方法,传入组件对象
     * @param component
     */
    public Decorator(Component component){
        this.component = component;
    }
    public void operation() {
        //转发请求给组件对象,可以在转发前后执行一些附加动作
        component.operation();
    }
}

ConcreteComponent

java 复制代码
public class ConcreteComponent extends Component{

    public void operation() {
        System.out.println("默认标准输出");
    }
}

ConcreteDecoratorA

java 复制代码
public class ConcreteDecoratorA extends Decorator{

    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    private void operationOne(){
        System.out.println("A ~ one ~");
    }
    private void operationTwo(){
        System.out.println("A ~ two ~");}

    @Override
    public void operation() {
        //调用父类方法,可以在调用前后执行一些附加动作
        operationOne();
        super.operation();
        operationTwo();
    }
}

ConcreteDecoratorB

java 复制代码
public class ConcreteDecoratorB extends Decorator{
    
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    private void operationOne(){
        System.out.println("B ~ one ~");
    }
    private void operationTwo(){
        System.out.println("B ~ two ~");}

    @Override
    public void operation() {
        //调用父类方法,可以在调用前后执行一些附加动作
        operationOne();
        super.operation();
        operationTwo();
    }
}

以上是相关类,Client中展示了使用方法:

java 复制代码
public class Client {
    public static void main(String[] args) {
    	//首先定义一个 "默认标准"
        Component c1 = new ConcreteComponent();
        //在默认基础上,包装上decoratorA的逻辑
        Decorator decoratorA = new ConcreteDecoratorA(c1);
        //执行包装过A的operation方法,输出见<1>
        decoratorA.operation();
        //在默认基础上,包装上B的逻辑
        Decorator decoratorB = new ConcreteDecoratorB(c1);
        //执行包装过B的operation方法,输出见<2>
        decoratorB.operation();
        //在B的基础上(B是基于默认标准的),包装上A的逻辑
        Decorator decoratorAB = new ConcreteDecoratorA(decoratorB);
        //执行A(B(c1))的operation方法,输出见<3>
        decoratorAB.operation();
    }
}

Client main方法的输出:

输出<1>:A包裹c1

A ~ one ~

默认标准输出

A ~ two ~

输出<2>:B包裹c1

B ~ one ~

默认标准输出

B ~ two ~

输出<3>:B包裹c1,A包裹B

A ~ one ~

B ~ one ~

默认标准输出

B ~ two ~

A ~ two ~


装饰器模式可以达到上述层层装饰的效果,可以在不改变默认标准实现的前提下,通过层层包裹逻辑,增加其功能。

下面再举个实际场景的例子。

电商平台购物时,我们总会看到一些商品这样的销售策略,基础版一个价格,在基础版上叠加更多的功能/配置,并通过赠送的辅助产品不同,设置成不同的套餐,每个套餐价格也各异,丰俭由人。

我们以笔记本电脑为例:

基础版为:一部笔记本电脑,3699元

超值版为:一部笔记本电脑+高端电脑包+品牌鼠标,3999元

豪华版为:一部笔记本电脑+高端电脑包+品牌鼠标+外接键盘+笔记本支架+USB扩展坞,4299元

我们有这样几个类:

INoteBookPackage 笔记本套餐抽象类;(相当于 Component )

BasicPackage,基础套餐(相当于 ConcreteComponent )

SuperValuePackageDecorator,超值套餐;(相当于ConcreteDecoratorA )

LuxuryPackageDecorator,豪华套餐;(相当于ConcreteDecoratorB )

Decorator,装饰器

具体代码如下:
INoteBookPackage

java 复制代码
public abstract class INoteBookPackage {
    protected abstract String getConfigMsg();
    protected abstract int getConfigPrice();
}

BasicPackage

java 复制代码
public class BasicPackage extends INoteBookPackage{
    public String getConfigMsg() {
        return "一台笔记本";
    }

    public int getConfigPrice() {
        return 3699;
    }
}

Decorator

java 复制代码
public abstract class Decorator extends INoteBookPackage{

    private INoteBookPackage noteBookPackage;

    public Decorator(INoteBookPackage noteBookPackage){
        this.noteBookPackage = noteBookPackage;
    }

    protected String getConfigMsg() {
        return noteBookPackage.getConfigMsg();
    }

    protected int getConfigPrice() {
        return noteBookPackage.getConfigPrice();
    }
}

SuperValuePackageDecorator

java 复制代码
public class SuperValuePackageDecorator extends Decorator{
    public SuperValuePackageDecorator(INoteBookPackage noteBookPackage) {
        super(noteBookPackage);
    }
    @Override
    protected String getConfigMsg() {
        return super.getConfigMsg()+"+高端电脑包+品牌鼠标";
    }
    @Override
    protected int getConfigPrice() {
        return super.getConfigPrice()+300;
    }
}

LuxuryPackageDecorator

java 复制代码
public class LuxuryPackageDecorator extends Decorator{
    public LuxuryPackageDecorator(INoteBookPackage noteBookPackage) {
        super(noteBookPackage);
    }
    @Override
    protected String getConfigMsg() {
        return super.getConfigMsg()+"+外接键盘+笔记本支架+USB扩展坞";
    }
    @Override
    protected int getConfigPrice() {
        return super.getConfigPrice()+300;
    }
}

Client

java 复制代码
public class Client {
    public static void main(String[] args) {
        INoteBookPackage noteBookPackage = new BasicPackage();
        System.out.println("默认标配:"+noteBookPackage.getConfigMsg()+" 价格:" + noteBookPackage.getConfigPrice());

        Decorator superValuePackage = new SuperValuePackageDecorator(noteBookPackage);
        System.out.println("超值套餐:"+superValuePackage.getConfigMsg()+" 价格:"+superValuePackage.getConfigPrice());

        Decorator luxuryPackage = new LuxuryPackageDecorator(superValuePackage);
        System.out.println("豪华套餐:"+luxuryPackage.getConfigMsg()+" 价格:"+luxuryPackage.getConfigPrice());
    }
}

Client 的main执行结果为:

shell 复制代码
默认标配:一台笔记本 价格:3699
超值套餐:一台笔记本+高端电脑包+品牌鼠标 价格:3999
豪华套餐:一台笔记本+高端电脑包+品牌鼠标+外接键盘+笔记本支架+USB扩展坞 价格:4299

以上为本文全部内容,感谢阅读。

相关推荐
熊大如如25 分钟前
Java 反射
java·开发语言
猿来入此小猿44 分钟前
基于SSM实现的健身房系统功能实现十六
java·毕业设计·ssm·毕业源码·免费学习·猿来入此·健身平台
teacher伟大光荣且正确1 小时前
Qt Creator 配置 Android 编译环境
android·开发语言·qt
goTsHgo1 小时前
Spring Boot 自动装配原理详解
java·spring boot
卑微的Coder1 小时前
JMeter同步定时器 模拟多用户并发访问场景
java·jmeter·压力测试
pjx9872 小时前
微服务的“导航系统”:使用Spring Cloud Eureka实现服务注册与发现
java·spring cloud·微服务·eureka
多多*2 小时前
算法竞赛相关 Java 二分模版
java·开发语言·数据结构·数据库·sql·算法·oracle
爱喝酸奶的桃酥2 小时前
MYSQL数据库集群高可用和数据监控平台
java·数据库·mysql
唐僧洗头爱飘柔95273 小时前
【SSM-SSM整合】将Spring、SpringMVC、Mybatis三者进行整合;本文阐述了几个核心原理知识点,附带对应的源码以及描述解析
java·spring·mybatis·springmvc·动态代理·ioc容器·视图控制器
骑牛小道士3 小时前
Java基础 集合框架 Collection接口和抽象类AbstractCollection
java