这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战
前言
一般情况下如果我们想要对一个对象进行扩展,会使用继承或组合的方式来进行,这个扩展的动作发生在编译时,比如在继承扩展时,子类的所有对象在编译时就已经确定有什么特性。
而如果需要在运行时按照不同的情况进行不同的功能扩展,并且不会对现有对象的功能进行添加和删除,则需要用装饰器模式来实现。
装饰器模式定义
装饰器模式(Decorator Design Pattern)用于在运行时修改对象的功能。同时,同一类的其他实例将不受此影响,因此单个对象将获得修改后的行为。装饰器设计模式是结构设计模式(如适配器模式、桥接模式、组合模式)的一种,它使用抽象类或具有组合的接口来实现。
假设我们想要实现不同类型的汽车,我们可以创建接口Car来定义汽车有哪些功能(接口中的方法),然后我们可以有一个基本款汽车实现类,进一步我们可以将基本款扩展到跑车和豪华车。实现层次结构如下图所示。
但是,如果我们想在运行时得到一辆同时具有跑车和豪华车特性的汽车,那么实现就会变得复杂,如果我们想进一步指定应该首先添加哪个特性,它就会变得更加复杂。现在想象一下,如果我们有10种不同的汽车,那么使用继承和组合的实现逻辑将会变得特别难以管理。为了解决这种编程问题,我们在java中应用了装饰器模式。
实现装饰器模式一般需要以下类型的组件。
组件接口
定义要实现的方法的接口或抽象类。在我们的例子中,Car将是组件接口。
1 | java复制代码public interface Car { |
组件实现
组件接口的基本实现。我们可以将BasicCar类作为组件实现。
1 | java复制代码public class BasicCar implements Car { |
装饰器
Decorator类实现了组件接口,并且它与组件接口具有has-a
关系。组件变量应该可以被子装饰器类访问,因此我们将这个变量设置为protected
。
1 | java复制代码public class CarDecorator implements Car { |
扩展基本装饰器功能并相应地修改组件行为。我们可以有具体的装饰器类,如LuxuryCar
和SportsCar
。
跑车装饰器实现:
1 | java复制代码public class SportsCar extends CarDecorator { |
豪华车装饰器实现:
1 | java复制代码public class LuxuryCar extends CarDecorator { |
测试类:
1 | java复制代码public class DecoratorPatternTest { |
在测试代码中,我们可以对目标对象BasicCar灵活扩展,并且SportCar和LuxuryCar的顺序可以改变。
装饰器模式类图
小结
装饰器设计模式有助于提供运行时修改功能,因此更加灵活。当选择数量较多时,易于维护和扩展。
装饰器模式在Java IO类中使用较多,如FileReader、BufferedReader等。
如果对你有帮助,点个赞是对我最大的鼓励。
本文转载自: 掘金