装饰者(Decorator)模式

装饰者模式是一种设计模式,能不修改对象结构的情况下,动态地为对象添加新的功能。对比于通过继承来扩展,它更为灵活。例如在咖啡店场景中,装饰者模式可以用于为咖啡添加如糖、牛奶等配料,避免大量继承类的产生。装饰者和代理模式相似,但代理模式通常在编译时确定对象关系,不支持多层嵌套,而装饰者模式能在运行时递归构建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

装饰者模式是允许向一个新对象添加新的功能,但又不改变其结构。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
就增加功能来说,装饰器模式相比生成子类更为灵活。
例子:
如果我们去咖啡店,有一种咖啡,该咖啡可以加糖,牛奶,奶泡等等,如果我们需要加糖和牛奶,常规的写法就是分别继承糖的接口和牛奶的接口,然后实现。但是如果添加种类很多的话,就会形成大量的继承类,给维护造成很大的麻烦。这就需要继承类来为其添加新功能了。

Coffee接口

public abstract class Coffee {
    public abstract int getPrice();
    public abstract String getName();
}

原始咖啡

public class SimpleCoffee extends Coffee {
    @Override
    public int getPrice() {
        return 10;
    }

    @Override
    public String getName() {
        return "原始咖啡";
    }
}

Decorator类

public abstract class Decorator extends Coffee {
    //用于传递Coffee对象
    public Coffee coffee;
    public Decorator(Coffee coffee){
        this.coffee = coffee;
    }
}

MilkDecorator类

public class MilkDecorator extends Decorator {
    public MilkDecorator(Coffee coffee){
        super(coffee);
    }
    @Override
    public int getPrice() {
        return coffee.getPrice()+10;
    }

    @Override
    public String getName() {
        return coffee.getName() + "milk";
    }

测试

public class Test {
    public static void main(String[] args) {
        Coffee coffee = new SimpleCoffee();
        coffee = new MilkDecorator(coffee);
        System.out.println(coffee.getPrice());
    }
}

如果你想加糖可以
coffee = new SugarDecorator(coffee);
等等
这样我们就可以方便的为咖啡提供各种配料了。

装饰者模式和代理模式的区别
两者都可以在不改变原始类的结构的前提下,为新对象提供新功能。但是两者也是有区别的:

在用法上:用代理模式,代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。并且,当我们使用装饰器模 式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。
运行时:使用代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,并不支持多层嵌套,而装饰者能够在运行时递归地被构造。
详细的可以看这个链接: https://www.cnblogs.com/jaredlam/archive/2011/11/08/2241089.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值