温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java中的装饰器模式是什么

发布时间:2021-07-08 17:49:28 来源:亿速云 阅读:109 作者:chen 栏目:大数据

本篇内容介绍了“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.
 *
 * <p><strong>Note:</strong> 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中的装饰器模式是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI