1. 什么是装饰模式
装饰模式(别名:包装器)
动态地给对象添加一些额外的职责。就功能来说装饰模式相比生成子类更为灵活。
2. 使用场景
装饰模式是动态地扩展一个对象的功能,而不需要改变原始类代码的一种成熟模式。在装饰模式中,“具体组件”类和“具体装饰”类是该模式中的最重要的两个角色。
3. 模式的结构和使用
装饰模式的结构中包括四种角色:
- 抽象组件(Component)
- 具体组件(ConcreteComponent)
- 装饰(Decorator)
- 具体装饰(ConcreteDecotator)
4. 简单例子
4.1 抽象组件: Bird.java
package indi.peter.designpattern.decoractor;
public abstract class Bird {
public abstract int fly();
}
4.2 具体组件 : Sparrow.java
package indi.peter.designpattern.decoractor;
public class Sparrow extends Bird{
public final int DISTANCE = 100;
public int fly() {
return DISTANCE;
}
}
4.3 装饰 (Decorator): Decorator.java
package indi.peter.designpattern.decoractor;
public abstract class Decorator extends Bird{
protected Bird bird;
public Decorator() {
}
public Decorator(Bird bird) {
this.bird = bird;
}
}
4.4 具体装饰(ConcreteDecotator): SparrowDecorator.java
package indi.peter.designpattern.decoractor;
public class SparrowDecorator extends Decorator{
public final int DISTANCE = 50; // eleFly方法能飞50米
SparrowDecorator(Bird bird) {
super(bird);
}
public int fly() {
int distance = 0;
distance = bird.fly() + eleFly();
return distance;
}
private int eleFly() { // 装饰者新添加的方法
return DISTANCE;
}
}
4.5 应用
package indi.peter.designpattern.decoractor;
public class Application {
public void needBird(Bird bird) {
int flyDistance = bird.fly();
System.out.println("这只鸟能飞行" + flyDistance + "米");
}
public static void main(String args[]) {
Application client = new Application();
Bird sparrow = new Sparrow();
Bird sparrowDecorator1 = new SparrowDecorator(sparrow);
Bird sparrowDecorator2 = new SparrowDecorator(sparrowDecorator1);
client.needBird(sparrowDecorator1);
client.needBird(sparrowDecorator2);
}
}
5. 模式应用到的开源框架
在 Spring Boot 中,装饰者模式被广泛应用于增强和扩展现有功能,同时保持核心逻辑的清晰和不变。这种模式在处理请求、响应、以及各种中间件中尤为常见,通过包装一个或多个组件来增加额外的行为或修改现有行为。以下是在 Spring Boot 中常见的使用装饰者模式的例子.
5.1 HTTP请求和响应的增强
在 Spring Web 框架中,装饰者模式常用于扩展 HttpServletRequest 和 HttpServletResponse 对象。这可以通过过滤器(Filter)实现,比如添加安全头、进行日志记录或者修改请求响应体。这样的处理允许开发者在不修改现有控制器逻辑的情况下,增加额外的处理逻辑。
5.2 Spring Security 的上下文包装
Spring Security 使用装饰者模式来增强安全功能,例如通过 SecurityContextHolder 管理认证和授权的上下文。这种模式使得在请求处理过程中能够随时访问用户的认证状态,而无需直接修改业务逻辑代码。
5.3 数据访问对象(DAO)的功能增强
在数据访问层,装饰者模式可用于增强数据访问对象的功能。例如,可以通过装饰者模式添加事务管理或缓存策略,这样,开发者可以在不更改主要数据访问逻辑的情况下,灵活地添加或修改功能。
5.4 AOP的装饰者应用
面向切面编程(AOP)本质上是一种装饰者模式的实现。通过AOP,可以在不改变原有方法逻辑的基础上,为方法调用装饰额外的行为,如日志记录、性能监控或事务控制等。这是通过定义切面(Aspect)和通知(Advice)来实现的。
5.5 响应体包装
在构建 REST API 时,ResponseEntity 类常被用来装饰响应体,允许开发者灵活地设置状态码、头信息和响应体内容。这个类提供了丰富的 API 来链式构建 HTTP 响应,是装饰者模式的一个典型应用。
5.6 资源处理策略的扩展
在静态资源管理中,Spring Boot 允许通过装饰者模式添加自定义的资源解析策略,比如版本控制、缓存策略等。这使得开发者可以在不改变基本资源服务功能的前提下,根据需求添加额外的资源处理策略。
6. 模式优点
- 被装饰者和装饰者是松耦合关系。由于装饰(Decorator)仅仅依赖于抽象组件(Component),因此具体装饰只知道它要装饰的对象是抽象组件的某一个子类的实例,但不需要知道是哪一个具体子类。
- 装饰模式满足“开-闭原则”。不必修改具体组件,就可以增加新的针对该具体组件的具体装饰。
- 可以使用多个具体装饰来装饰具体组件的实例。
富贵必从勤苦得,男儿须读五车书。加油少年郎!!!