装饰者设计模式用于在运行时修改对象的功能。同时,同一类的其他实例不会受到影响,因此单个对象获得了修改后的行为。装饰者设计模式是结构性设计模式之一(例如适配器模式,桥接模式,组合模式),并使用抽象类或接口与组合来实现。
装饰者设计模式
我们使用继承或组合来扩展对象的行为,但这是在编译时完成的,并且适用于类的所有实例。我们无法在运行时添加任何新功能或删除任何现有行为 – 这就是装饰器模式的用武之地。假设我们想要实现不同种类的汽车 – 我们可以创建接口Car来定义装配方法,然后我们可以有一个基本汽车,进一步扩展为运动汽车和豪华汽车。实现层次结构将如下图所示。 但是,如果我们想在运行时获取既具有运动汽车特性又具有豪华汽车特性的汽车,则实现变得复杂,如果我们还想指定应该先添加哪些特性,它会变得更加复杂。现在想象一下,如果我们有十种不同种类的汽车,使用继承和组合的实现逻辑将无法管理。为了解决这种编程情况,我们在Java中应用装饰器模式。我们需要以下类型来实现装饰器设计模式。
-
组件接口 – 定义将要实现的方法的接口或抽象类。在我们的例子中,
Car
将是组件接口。package com.journaldev.design.decorator; public interface Car { public void assemble(); }
-
组件实现 – 组件接口的基本实现。我们可以将
BasicCar
类作为我们的组件实现。package com.journaldev.design.decorator; public class BasicCar implements Car { @Override public void assemble() { System.out.print("基础汽车。"); } }
-
装饰者 – 装饰者类实现了组件接口,并且与组件接口存在一个HAS-A关系。组件变量应该对子装饰者类可访问,因此我们将把这个变量设为protected。
package com.journaldev.design.decorator; public class CarDecorator implements Car { protected Car car; public CarDecorator(Car c){ this.car=c; } @Override public void assemble() { this.car.assemble(); } }
-
具体装饰者 – 扩展基本装饰者功能并相应地修改组件行为。我们可以有具体装饰者类如
LuxuryCar
和SportsCar
。package com.journaldev.design.decorator; public class SportsCar extends CarDecorator { public SportsCar(Car c) { super(c); } @Override public void assemble(){ super.assemble(); System.out.print(" 添加了跑车的特性。"); } }
package com.journaldev.design.decorator; public class LuxuryCar extends CarDecorator { public LuxuryCar(Car c) { super(c); } @Override public void assemble(){ super.assemble(); System.out.print(" 添加了豪华车的特性。"); } }
装饰者设计模式 – 类图
装饰者设计模式测试程序
package com.journaldev.design.test;
import com.journaldev.design.decorator.BasicCar;
import com.journaldev.design.decorator.Car;
import com.journaldev.design.decorator.LuxuryCar;
import com.journaldev.design.decorator.SportsCar;
public class DecoratorPatternTest {
public static void main(String[] args) {
Car sportsCar = new SportsCar(new BasicCar());
sportsCar.assemble();
System.out.println("\n*****");
Car sportsLuxuryCar = new SportsCar(new LuxuryCar(new BasicCar()));
sportsLuxuryCar.assemble();
}
}
请注意,客户端程序可以在运行时创建不同类型的对象,并且它们可以指定执行顺序。上述测试程序的输出是:
Basic Car. Adding features of Sports Car.
*****
Basic Car. Adding features of Luxury Car. Adding features of Sports Car.
装饰者设计模式 – 重要要点
- 装饰者设计模式有助于提供运行时修改的能力,因此更灵活。当选择的数量较多时,易于维护和扩展。
- 装饰者设计模式的缺点是它使用了许多类似类型的对象(装饰者)。
- 修饰者模式在许多Java IO类中广泛使用,例如FileReader、BufferedReader等。
Source:
https://www.digitalocean.com/community/tutorials/decorator-design-pattern-in-java-example