这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战
装饰器模式
概念
装饰器模式(Decorator Pattern),也称为包装模式(Wrapper Pattern),是指允许向一个现有的对象添加新的功能,同时又不改变其结构。或者说在不改变原有对象的基础上,将功能附加到原有对象上,提供了比继承更有弹性的替代方案,根据类的创建过程,装饰器模式属于结构型模式。
装饰器模式的主要核心就是功能扩展,可以透明并且动态的扩展对象类的功能。
装饰器应用场景
-
SpringSession中如何进行session与redis关联?
-
MyBatisPlus提取了QueryWrapper,这是什么?
-
Spring中的BeanWrapper是做什么?包装了Bean。bean的功能增强?
-
SpringWebflux中的WebHandlerDecorator?
-
已存的类,每一天在某个功能使用的时候发现不够,就可以装饰器。
装饰器模式的基本用法
装饰器模式一般情况下有四类角色
-
抽象构件(Component)角色:可以是一个类或者一个接口类,该类充当被装饰类的原始对象,规定了被装饰类对象的行为。
-
具体构件(ConcreteComponent)角色:实现或者继承抽象构件(Component)角色的的一个具体对象,即
被装饰对象,通过装饰角色为其添加一些职责。 -
抽象装饰(Decorator)角色:通用的装饰ConcreteComponent的装饰器,其内部必然是有一个属性指向抽象构件,一般实现就是一个抽象类。并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
-
具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任,理论上每个ConcreteDecorator都扩展了Component对象的一个功能。
下面是装饰器模式的通用写法。
- Shape(抽象构件角色)
public interface Shape {
void draw();
}
创建一个画图Shape类
- Circle(具体构件角色)
public class Circle implements Shape{
@Override
public void draw() {
System.out.println("Shape: Circle");
}
}
创建画圆形的类
- Rectangle(具体构件角色)
public class Rectangle implements Shape{
@Override
public void draw() {
System.out.println("Shape: Rectangle");
}
}
创建长方形Rectangle类
- ShapeDecorator(抽象装饰角色)
public abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape) {
this.decoratedShape = decoratedShape;
}
@Override
public void draw() {
decoratedShape.draw();
}
}
创建抽象装饰器画图ShapeDecorator类,里面定义有参构造方法和重写了draw画图方法。
- RedShapeDecorator(具体装饰角色)
public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
}
private void setRedBorder(Shape decoratedShape) {
System.out.println("Border Color: Red");
}
}
创建了具体装饰器RedShapeDecorator类,该类继承了ShapeDecorator装饰器,然后重写了属于自己的draw方法并新建属于自己的setRedBorder方法设置了特定的边框颜色。
- UML结构图
通过上述代码和uml结构,通过一层一层的嵌套而不一直继承来实现各自的方法。
装饰器模式的优点和缺点
优点
-
装饰器模式是继承的有力补充,但是装饰器模式比继承灵活,他在不改变原有对象的情况下动态地给一个对象新增了扩展的功能。
-
装饰器模式通过使用不同的装饰及这些装饰类的排列组合,可以实现不同效果和不同的功能。
-
装饰器模式完全遵守开闭原则。即对新增开放,对修改关闭。
缺点
-
装饰器模式使用过多会导致增加许多子类,过度使用会增加程序的复杂性。
-
装饰器模式在进行动态装饰时,多层装饰会使代码更加复杂,导致可读性降低
装饰器模式和代理模式的区别
- 相同点
装饰器模式和代理模式从设计模式的分类看都属于结构型模式,因为装饰器和代码模式都是用来组合的关系,然后两者都通过对自身对象的方法进行增强,达到自己想要的效果。
-
不同点
-
装饰器模式是一种特殊的代理模式
-
代理模式主要是注重于代理过程的控制,即注重对与对象某一功能的流程控制,代理模式可以控制对象做一些事情,只要核心在于借助对象完成某一流程,而非使用对象的功能。
-
装饰器模式强调时对于自身的功能扩展,不关心外界如何调用自己,只注重于自己的动态扩展和增强,但是装饰器模式对于装饰前还是装饰后都还是对象本身。
-