装饰器模式
装饰者模式是一种结构型模式,它对现有的类进行包装,允许向一个现有的对象添加现有的功能,同时又不改变其结构。
这种模式创建了一个新的装饰器类,用来包装原有的类。并在保持类签名完整性的情况下提供了额外的功能。
意图:动态地给一个对象添加额外的职责,就新增红能来说,装饰器模式相比于生成子类更加灵活。
主要解决:通常我们为了增加一个类的功能,经常使用继承的方式,由于继承引入静态代码的特征,并且随着扩展功能的增多,子类会很膨胀。
如何使用;在不想增加子类的情况下使用。
如何解决:将具体功能职责进行划分,同时继承装饰者模式。
关键代码: Component类充当抽象角色,不负责具体实现。 装饰者类继承和引用Component类,具体扩展类重写父类方法。
有点:装饰类和被装饰类可以独立发展,不会互相耦合。装饰模式是继承很好的的一个替代模式。
抽象组件:
public abstract class Beverage {
String description = "Unknow Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}
抽象装饰者类
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
具体组件
public class Espresso extends Beverage{
public Espresso(){
description = "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
具体装饰者
public class Mocha extends CondimentDecorator{
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
@Override
public double cost() {
return 0.20 + beverage.cost();
}
}
单元测试
public class MochaTest {
@Test
public void getDescription() {
Beverage beverage = new Espresso();
beverage = new Mocha(beverage);
System.out.println(beverage.getDescription());
}
@Test
public void cost() {
Beverage beverage = new Espresso();
beverage = new Mocha(beverage);
System.out.println(beverage.cost());
}
}
测试结果:
2.19
Espresso, Mocha
装饰者和被装饰者必须是一样的类型,也就是有共同的超类。这是相当关键的地方,所以我们利用继承来达到类型匹配,而不是利用继承获得“行为”。
装饰者在和组件结合时,就是在加入新的行为。所得到的行为并不是继承自超类,而是由组合对象得到的。
如果依赖继承,那么类的行为只能在编译时静态决定。换句话说,行为不是来自超类,就是来自子类覆盖后的版本。但是利用组合,可以把装饰者混合着用,而且是在“运行时".
因此这样就可以在任何时候,实现新的装饰者增加新的行为。如果依赖继承,每当需要新行为时,还得修改现有的代码。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)