千家信息网

java中的装饰器模式是什么

发表于:2025-02-03 作者:千家信息网编辑
千家信息网最后更新 2025年02月03日,本篇内容介绍了"java中的装饰器模式是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. 基本
千家信息网最后更新 2025年02月03日java中的装饰器模式是什么

本篇内容介绍了"java中的装饰器模式是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1. 基本概念

装饰器模式(Decorator),又名包装(Wrapper)模式。允许向一个现有的对象添加新的功能同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

2. 使用场景

2.1 HttpServletRequestWrapper

/** * Provides a convenient implementation of the HttpServletRequest interface that * can be subclassed by developers wishing to adapt the request to a Servlet. * This class implements the Wrapper or Decorator pattern. Methods default to * calling through to the wrapped request object. * * @see javax.servlet.http.HttpServletRequest * @since v 2.3 */public class HttpServletRequestWrapper extends ServletRequestWrapper implements        HttpServletRequest {    /**     * Constructs a request object wrapping the given request.     *     * @param request The request to wrap     *     * @throws java.lang.IllegalArgumentException     *             if the request is null     */    public HttpServletRequestWrapper(HttpServletRequest request) {        super(request);    }}

HttpServletRequestWrapper是一个什么都没做的具体装饰实现类(concerteDecorator),不过它即继承了装饰实现类,又实现了HttpservletRequst。这里什么都不做是有道理的,因为要对请求添加何种功能事先是没法知道的,不可能盲目的添加。所以,这种里的装饰模式的应用场景:适合对默认目标实现未知或者不易扩展的情况。
装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。那么在实际应用中遇到需增强对象的方法时,到底选用哪种方式比较好呢?这个没有具体的定式,只能是根据具体的需求来采用具体的方式,不过有一种情况下,必须使用Decorator设计模式:即被增强的对象,开发人员只能得到它的对象,无法得到它的class文件
比如request、response对象,开发人员之所以在servlet中能通过sun公司定义的HttpServletRequest/Response接口去操作这些对象,是因为Tomcat服务器厂商编写了request、response接口的实现类。web服务器在调用servlet时,会用这些接口的实现类创建出对象,然后传递给servlet程序。此种情况下,由于开发人员根本不知道服务器厂商编写的request、response接口的实现类是哪个?在程序中只能拿到服务器厂商提供的对象,因此就只能采用Decorator设计模式对这些对象进行增强。

当我们在使用filter的时候却会发现至少有一半的时间我们都想改变HttpServletRequest对象的参数。如:用filter在HttpServletRequest对象到达Servlet之前将用户输入的空格去掉。但是由于java.util.Map包装的HttpServletRequest对象的参数是不可改变的,那要怎么办呢?幸运的是,尽管我们不能改变对象本身但是可以通过装饰器来改变其状态。想要改变HttpServletRequest中的参数,可以通过HttpServletRequest的装饰类HttpServletRequestWrapper来实现,只需要在装饰类中按照需要重写其getParameter(getParameterValues)方法即可。

2.2 ServerWebExchangeDecorator

WebFlux中采用的装饰器,原理类似,可以对请求和响应参数进行修改(注意直接在过滤器中修改处于安全考虑会抛出异常UnsupportedOperationException,具体解决可以参考xbuba.com-如何在Spring WebFilter中添加自定义标头?)。

/** * A convenient base class for classes that need to wrap another * {@link ServerWebExchange}. Pre-implements all methods by delegating to the * wrapped instance. * * 

Note: if the purpose for using a decorator is to override * properties like {@link #getPrincipal()}, consider using * {@link ServerWebExchange#mutate()} instead. * * @author Rossen Stoyanchev * @since 5.0 * * @see ServerWebExchange#mutate() */public class ServerWebExchangeDecorator implements ServerWebExchange { private final ServerWebExchange delegate; protected ServerWebExchangeDecorator(ServerWebExchange delegate) { Assert.notNull(delegate, "ServerWebExchange 'delegate' is required."); this.delegate = delegate; }}

/** * Wraps another {@link ServerHttpRequest} and delegates all methods to it. * Sub-classes can override specific methods selectively. * * @author Rossen Stoyanchev * @since 5.0 */public class ServerHttpRequestDecorator implements ServerHttpRequest {        private final ServerHttpRequest delegate;        public ServerHttpRequestDecorator(ServerHttpRequest delegate) {                Assert.notNull(delegate, "Delegate is required");                this.delegate = delegate;        }}

"java中的装饰器模式是什么"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0