Java 装饰模式(Decorator Pattern)是一种结构型设计模式,它允许你以透明的方式动态地向对象添加额外的功能,而不需要修改其源代码。这种模式是通过创建一个装饰器类,该类包装原始类的实例来实现的。装饰器类实现与原始类相同的接口,并将原始对象包装在内,以便在不改变原始对象的情况下增加或修改其行为。
装饰模式的主要角色包括:
-
组件接口(Component):定义了原始对象和装饰器对象的公共接口。
-
具体组件(Concrete Component):实现了组件接口,是具体的原始对象,它定义了基本的行为。
-
装饰器(Decorator):实现了组件接口,同时包含一个对组件对象的引用。装饰器可以动态地添加额外的功能,它可以包装具体组件或其他装饰器。
-
具体装饰器(Concrete Decorator):实现了装饰器接口,它具体扩展或修改组件的行为。
下面是一个简单示例,演示如何在 Java 中实现装饰模式:
// 组件接口
interface Coffee {
String getDescription();
double cost();
}
// 具体组件
class SimpleCoffee implements Coffee {
@Override
public String getDescription() {
return "Simple Coffee";
}
@Override
public double cost() {
return 2.0;
}
}
// 装饰器
abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee decoratedCoffee) {
this.decoratedCoffee = decoratedCoffee;
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription();
}
@Override
public double cost() {
return decoratedCoffee.cost();
}
}
// 具体装饰器
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
@Override
public String getDescription() {
return super.getDescription() + ", with Milk";
}
@Override
public double cost() {
return super.cost() + 0.5;
}
}
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
@Override
public String getDescription() {
return super.getDescription() + ", with Sugar";
}
@Override
public double cost() {
return super.cost() + 0.2;
}
}
public class DecoratorPatternDemo {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
System.out.println("Cost: " + coffee.cost() + ", Description: " + coffee.getDescription());
Coffee milkCoffee = new MilkDecorator(coffee);
System.out.println("Cost: " + milkCoffee.cost() + ", Description: " + milkCoffee.getDescription());
Coffee sugarMilkCoffee = new SugarDecorator(milkCoffee);
System.out.println("Cost: " + sugarMilkCoffee.cost() + ", Description: " + sugarMilkCoffee.getDescription());
}
}
在上述示例中,我们有一个 Coffee
接口表示咖啡,以及一个具体组件 SimpleCoffee
,它是基本的咖啡对象。然后,我们有装饰器 CoffeeDecorator
和两个具体装饰器 MilkDecorator
和 SugarDecorator
。这些装饰器类扩展了咖啡的功能,例如添加牛奶和糖。
客户端代码可以以透明的方式使用这些装饰器,通过组合装饰器对象来创建具有不同功能的咖啡。这使得可以在不修改 SimpleCoffee
类的情况下,动态地添加和组合功能,从而实现了装饰模式的目标。