1.装饰器模式定义
装饰器模式(Decorator Pattern)是一种结构型设计模式,它可以在不改变原有对象的基础上,动态地给对象添加新的职责和行为。 该模式的核心思想是以递归的方式,通过将对象包装在装饰器对象中,来不断添加新的行为和职责。装饰器模式的结构包括以下角色:
Component(抽象构件):定义一个抽象接口,用于表示被装饰对象的基本行为。
ConcreteComponent(具体构件):实现抽象构件接口,定义一个具体的对象,是被装饰的对象。
Decorator(抽象装饰器):维护一个指向抽象构件的引用,并定义一个与Component接口一致的接口,用于扩展Component的职责。
ConcreteDecorator(具体装饰器):实现抽象装饰器接口,扩展Component的职责,并维护一个指向Component的引用。
2.装饰器模式优点
可以动态地扩展对象的职责和行为,避免使用继承带来的静态扩展限制。在使用继承时,子类的职责和行为是在编译时确定的,而装饰器模式可以在运行时动态地添加新的职责和行为。这使得装饰器模式具有更强的灵活性,可以根据需要进行动态组合和扩展。
可以组合多个装饰器对象,实现复杂的功能扩展。在装饰器模式中,可以通过组合多个装饰器对象来实现不同的职责和行为扩展。这使得装饰器模式可以应对复杂的功能扩展需求,同时也使得代码更加清晰和易于维护。
装饰器模式符合“开闭原则”,可以在不改变原有代码的情况下,添加新的职责和行为。在装饰器模式中,可以通过添加新的装饰器类来扩展对象的职责和行为,而不需要修改原有代码。这使得装饰器模式具有很好的扩展性和维护性。
3.装饰器模式缺点
装饰器模式会增加系统的复杂度和开销,因为需要创建多个装饰器对象。在使用装饰器模式时,可能需要创建多个装饰器对象来实现不同的职责和行为扩展。这会增加系统的复杂度和开销,同时也会降低系统的性能。
装饰器模式容易造成设计上的混乱,因为不同的装饰器对象可能会有相互依赖关系。在使用装饰器模式时,可能会出现不同的装饰器对象之间存在相互依赖关系的情况,这会增加系统的复杂度和不稳定性。
装饰器模式的嵌套层次过多可能会影响系统的性能。在使用装饰器模式时,可能会出现装饰器对象的嵌套层次过多的情况,这会增加系统的复杂度和降低系统的性能。因此,在使用装饰器模式时需要注意控制装饰器对象的嵌套层次。
4.装饰器设计模式 示例代码
传统设计模式讲解时使用的示例代码,大都采用与读者日常生活接解的业务系统没有多大关联关系。以致大部分读者无法做到学以致用,学完就忘记。本文采用使用日常生活中随处可见的电商相关业务来编写实现代码
假设我们有一个电商平台,需要对商品进行价格计算,同时还需要对价格进行打折和折扣券的处理,我们可以使用装饰器模式来实现该功能。
首先定义一个抽象构件Component,表示商品的基本行为:
public interface Component {
double getPrice();
}
然后定义具体构件ConcreteComponent,表示一个具体的商品对象:
public class ConcreteComponent implements Component {
private double price;
public ConcreteComponent(double price) {
this.price = price;
}
@Override
public double getPrice() {
return price;
}
}
接着定义抽象装饰器Decorator,用于扩展Component的职责:
public abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
@Override public double getPrice() {
return component.getPrice();
}
}
最后定义具体装饰器ConcreteDecorator,实现抽象装饰器接口,扩展Component的职责,并维护一个指向Component的引用。
例如,我们可以定义一个DiscountDecorator,用于对商品价格进行打折处理:
public class DiscountDecorator extends Decorator {
private double discount;
public DiscountDecorator(Component component, double discount) {
super(component); this.discount = discount;
}
@Override
public double getPrice() {
return component.getPrice() * discount;
}
}
我们还可以定义一个CouponDecorator,用于对商品价格进行折扣券处理:
public class CouponDecorator extends Decorator {
private double coupon;
public CouponDecorator(Component component, double coupon) {
super(component);
this.coupon = coupon;
}
@Override
public double getPrice() {
return component.getPrice() - coupon;
}
}
这样,我们就可以通过组合不同的装饰器对象,对商品的价格进行灵活的计算和处理:
Component product = new ConcreteComponent(100.0);
// 打八折
product = new DiscountDecorator(product, 0.8);
// 减10元
product = new CouponDecorator(product, 10.0);
// 计算最终价格
double price = product.getPrice();
下面展示了如何通过嵌套多个装饰器对象来实现复杂的功能:
interface Component { void operation(); }
class ConcreteComponent implements Component { public void operation() { System.out.println("ConcreteComponent operation"); } }
abstract class Decorator implements Component { protected Component component;
public Decorator(Component component) { this.component = component; }
public void operation() { component.operation(); } }
class ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component component) { super(component); }
public void operation() { super.operation(); addBehaviorA(); }
private void addBehaviorA() { System.out.println("add Behavior A"); } }
class ConcreteDecoratorB extends Decorator { public ConcreteDecoratorB(Component component) { super(component); }
public void operation() { super.operation(); addBehaviorB(); }
private void addBehaviorB() { System.out.println("add Behavior B"); } }
class ConcreteDecoratorC extends Decorator { public ConcreteDecoratorC(Component component) { super(component); }
public void operation() { super.operation(); addBehaviorC(); }
private void addBehaviorC() { System.out.println("add Behavior C"); } }
public class DecoratorDemo { public static void main(String[] args) { Component component = new ConcreteComponent(); Component decoratorA = new ConcreteDecoratorA(component); Component decoratorB = new ConcreteDecoratorB(decoratorA); Component decoratorC = new ConcreteDecoratorC(decoratorB); decoratorC.operation(); } } ```
在这个示例中,我们定义了一个抽象组件类 `Component` 和一个具体组件类 `ConcreteComponent` ,还定义了三个具体装饰器类 `ConcreteDecoratorA`、`ConcreteDecoratorB` 和 `ConcreteDecoratorC`。它们都继承自 `Decorator` 类,并通过嵌套其他装饰器对象来增加自己的职责。
在 `main()` 方法中,我们首先创建了一个具体组件对象 `ConcreteComponent` ,然后依次创建了三个装饰器对象 `ConcreteDecoratorA`、`ConcreteDecoratorB` 和 `ConcreteDecoratorC`,并将它们嵌套在一起使用。最后调用 `decoratorC.operation()` 方法输出结果,并观察其中添加了哪些行为。
这个示例展示了如何使用装饰器模式动态地为组件对象添加职责,并通过嵌套多个装饰器对象来实现复杂的功能。由于每个装饰器对象和被装饰对象具有相同的接口,因此可以方便地组合多个装饰器对象,并使得整个系统变得更加灵活。
为什么被装饰对象和装饰对象具有相同的接口 ?