您好,登录后才能下订单哦!
本篇内容介绍了“java中的装饰器模式是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
装饰器模式(Decorator),又名包装(Wrapper)模式。允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
/** * 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)方法即可。
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中的装饰器模式是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。