结构设计模式 - 装饰设计模式
装饰器设计模式用于在运行时修改对象的功能。同时,同一类的其他实例不会受此影响,因此单个对象将获得已修改的行为。装饰器设计模式是结构设计模式之一(如Adapter Pattern,Bridge Pattern,Composite Pattern),并使用抽象类或接口与组合来实现。
目录[ 隐藏 ]
我们使用继承或组合来扩展对象的行为,但这是在编译时完成的,它适用于类的所有实例。我们无法在运行时添加任何删除任何现有行为的新功能 - 这就是Decorator模式出现的时候。
假设我们想要实现不同种类的汽车 - 我们可以创建界面Car来定义组装方法然后我们可以拥有一辆Basic汽车,我们还可以将它扩展到跑车和豪华轿车。实现层次结构将如下图所示。
但是如果我们想要在运行时获得具有跑车和豪华车功能的汽车,那么实施变得复杂,如果我们想要指定哪些功能应该首先添加,它会变得更加复杂。现在想象一下,如果我们有十种不同类型的汽车,使用继承和组合的实现逻辑将无法管理。为了解决这种编程情况,我们在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("Basic Car."); } }
- Decorator - Decorator类实现组件接口,它与组件接口具有HAS-A关系。组件变量应该可以被子装饰器类访问,因此我们将保护此变量。
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(); } }
- Concrete Decorators - 扩展基本装饰器功能并相应地修改组件行为。我们可以将具体的装饰器类作为
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(" Adding features of Sports Car."); } }
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(" Adding features of Luxury Car."); } }
装饰设计模式 - 类图
装饰设计模式测试程序
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();
}
}
请注意,客户端程序可以在运行时创建不同类型的Object,它们也可以指定执行顺序。
上述测试程序的输出是:
Basic Car. Adding features of Sports Car.
***** Basic Car. Adding features of Luxury Car. Adding features of Sports Car.
装饰设计模式 - 重点
- 装饰器设计模式有助于提供运行时修改能力,因此更灵活。当选择的数量更多时,它易于维护和扩展。
- 装饰器设计模式的缺点是它使用了许多类似的对象(装饰器)。
- 装饰器模式在Java IO类中经常使用,例如FileReader,BufferedReader等。