设计模式--装饰器模式
装饰器模式
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许我们向一个现有的对象添加新的功能,同时又不改变其结构。就增加功能来说,装饰器模式相比生成子类更为灵活。这种模式创建了一个包装对象,也就是装饰器,来包裹真实的对象。
装饰器模式的主要组成部分
组件接口(Component):定义一个对象接口,可以给这些对象动态地添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
具体组件(ConcreteComponent):定义了一个具体的对象,也可以给这个对象添加一些职责。
装饰角色(Decorator):持有一个组件(Component)对象的引用,并定义一个与组件接口一致的接口。
具体装饰角色(ConcreteDecorator):负责给组件添加新的职责。
装饰器模式的工作方式
装饰器类:继承自装饰器角色类,它包含一个指向组件对象的引用,并定义了一个与组件接口一致的接口。
具体装饰器:负责给组件添加新的功能。
优点
扩展性:装饰器模式提供了比继承更有弹性的替代方案(扩展)。
灵活性:通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。
缺点
多层装饰较复杂:如果多层装饰器嵌套,可能会导致调用栈过深,从而影响性能。
案例:
假设我们有一个咖啡类,它提供基本的咖啡类型(如美式、拿铁),我们想要通过装饰器模式给咖啡添加额外的功能,比如加奶泡、加糖等。
// 具体组件
interface Coffee {
double getCost();
String getDescription();
}
// ConcreteComponent
class SimpleCoffee implements Coffee {
private String description = "Simple Coffee";
@Override
public double getCost() {
return 2.0;
}
@Override
public String getDescription() {
return description;
}
}
// 装饰角色
abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee decoratedCoffee) {
this.decoratedCoffee = decoratedCoffee;
}
@Override
public double getCost() {
return decoratedCoffee.getCost();
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription();
}
}
// 具体装饰角色
class MilkCoffee extends CoffeeDecorator {
public MilkCoffee(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
@Override
public double getCost() {
return super.getCost() + 0.5;
}
@Override
public String getDescription() {
return super.getDescription() + ", Milk";
}
}
// 具体装饰角色
class SugarCoffee extends CoffeeDecorator {
public SugarCoffee(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
@Override
public double getCost() {
return super.getCost() + 0.3;
}
@Override
public String getDescription() {
return super.getDescription() + ", Sugar";
}
}
// 客户端调用
public class DecoratorPatternDemo {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
coffee = new MilkCoffee(coffee);
coffee = new SugarCoffee(coffee);
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
}
}
在这个例子中,SimpleCoffee 是具体的组件,CoffeeDecorator 是装饰器角色,而 MilkCoffee 和 SugarCoffee 是具体的装饰器,它们给咖啡添加了新的功能(加奶泡、加糖)而不需要修改 SimpleCoffee 的代码。