什么是装饰器模式
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许动态地向对象添加新的行为,而无需修改原始对象的结构。通过将对象包装在一个或多个装饰器对象中,装饰器模式可以增强原始对象的功能。
装饰器组件
-
Component(组件):这是被装饰的对象的接口或抽象类。它定义了对象的行为。
-
ConcreteComponent(具体组件):这是实现了
Component
接口的具体类。它表示要被装饰的原始对象。 -
Decorator(装饰器):这是一个抽象类或接口,继承自
Component
。它包含对Component
对象的引用,并为原始对象提供额外的行为。 -
ConcreteDecorator(具体装饰器):这是实现了
Decorator
的具体类。它对原始对象的行为进行增强,并在必要时调用被装饰对象的方法。
优点
- 灵活性和可扩展性:可以在运行时动态地添加或删除装饰器,以增强对象的功能。
- 代码复用:装饰器可以重复使用,以增加不同对象的功能。
- 遵循开放-封闭原则:通过添加装饰器来扩展对象的行为,而不修改原始对象的结构。
举个例子
依旧是使用我们之前的咖啡的例子
// Component接口
interface Coffee {double cost();String description();
}// ConcreteComponent
class BasicCoffee implements Coffee {public double cost() {return 2.0; // 基础咖啡的价格}public String description() {return "Basic Coffee"; // 基础咖啡的描述}
}// Decorator抽象类
abstract class CoffeeDecorator implements Coffee {protected Coffee coffee;public CoffeeDecorator(Coffee coffee) {this.coffee = coffee;}
}// ConcreteDecorator
class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee coffee) {super(coffee);}public double cost() {return coffee.cost() + 0.5; // 添加牛奶的价格}public String description() {return coffee.description() + ", Milk"; // 添加牛奶的描述}
}class SugarDecorator extends CoffeeDecorator {public SugarDecorator(Coffee coffee) {super(coffee);}public double cost() {return coffee.cost() + 0.2; // 添加糖的价格}public String description() {return coffee.description() + ", Sugar"; // 添加糖的描述}
}// 使用装饰器模式
public class Main {public static void main(String[] args) {// 创建一个基础咖啡Coffee coffee = new BasicCoffee();// 添加牛奶装饰器coffee = new MilkDecorator(coffee);// 再次添加糖装饰器coffee = new SugarDecorator(coffee);// 输出咖啡的描述和价格System.out.println("Description: " + coffee.description());System.out.println("Cost: " + coffee.cost());}
}
我们创建了一个基础咖啡对象 BasicCoffee
,然后动态地向它添加装饰器 MilkDecorator
和 SugarDecorator
。这些装饰器增强了原始对象的功能,提供了灵活性和可扩展性。这像不像一个Class级别的建造者模式。
思考
都是对功能进行增强,那么代理模式和装饰器模式有什么区别呢?
往期推荐
金三银四面试题(二十一):代理模式知多少?2024-04-16
金三银四面试题(二十):单例模式知多少?2024-04-15
金三银四面试题(十九):MySQL中的锁2024-04-09
MySQL基础练习题:习题7-112024-04-09
金三银四面试题(十八):MySQL索引2024-04-08
MySQL基础练习题:习题4562024-04-08
金三银四面试题(十七):MySQL面试都问什么(2)2024-04-07
MySQL基础练习题:习题2-32024-04-07
MySQL基础练习题:创建数据库2024-04-07
金三银四面试题(十六):MySQL面试都问什么(1)2024-04-07