装饰器设计模式初探及Java中实际应用举例
本篇随笔主要介绍用Java实现简单的装饰器设计模式:
先来看一下装饰器设计模式的类图:

从图中可以看到,我们可以装饰Component接口的任何实现类,而这些实现类也包括了装饰器本身,装饰器本身也可以再被装饰。
下面是用Java实现的简单的装饰器设计模式,提供的是从基本的加入咖啡入手,可以继续加入牛奶,巧克力,糖的装饰器系统。
interface Component {
void method();
}
class Coffee implements Component {
@Override
public void method() {
// TODO Auto-generated method stub
System.out.println("倒入咖啡");
}
}
class Decorator implements Component {
public Component comp;
public Decorator(Component comp) {
this.comp = comp;
}
@Override
public void method() {
// TODO Auto-generated method stub
comp.method();
}
}
class ConcreteDecorateA extends Decorator {
public Component comp;
public ConcreteDecorateA(Component comp) {
super(comp);
this.comp = comp;
}
public void method1() {
System.out.println("倒入牛奶");
}
public void method2() {
System.out.println("加入糖 ");
}
public void method() {
super.method();
method1();
method2();
}
}
class ConcreteDecorateB extends Decorator {
public Component comp;
public ConcreteDecorateB(Component comp) {
super(comp);
this.comp = comp;
}
public void method1() {
System.out.println("加入巧克力");
}
public void method() {
super.method();
method1();
}
}
public class TestDecoratePattern {
public static void main(String[] args) {
Component comp = new Coffee();
comp.method();
System.out.println("--------------------------------------------------");
Component comp1 = new ConcreteDecorateA(comp);
comp1.method();
System.out.println("--------------------------------------------------");
Component comp2 = new ConcreteDecorateB(comp1);
comp2.method();
System.out.println("--------------------------------------------------");
Component comp3 = new ConcreteDecorateB(new ConcreteDecorateA(new Coffee()));
comp3.method();
System.out.println("--------------------------------------------------");
Component comp4 = new ConcreteDecorateA(new ConcreteDecorateB(new Coffee()));
comp4.method();
}
}
运行结果:

装饰器设计模式可以使得我们自由的,以任意顺序导入巧克力,牛奶,咖啡和糖。可以实现多层,任意顺序的装饰。
Java中实际应用举例:
1、java io流
以下一句代码即体现了装饰器设计模式的应用:
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(new File(filePath), true)));
PrintWriter类及BufferedWriter类就相当于上面装饰器设计模式类图中的ConcreteDecorateA 与 ConcreteDecorateB,FileWriter类则相当于上面类图中的ConcreteComponent类,PrintWriter类的构造器实际接受的是一个Writer类的对象,在这里即为BufferedWriter类的对象,然后对这个Writer类的write方法进行装饰。
2、web应用中在filter类中实现自定义的输入输出
filter类实现如下:
public class AllFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//自定义输出流
ServletResponse compressionResponse = new CompressionResponseWrapper((HttpServletResponse) servletResponse);
//把自定义的输出流传递到用户实现的servlet中去
filterChain.doFilter(servletRequest, compressionResponse);
}
@Override
public void destroy() {
}
}
其中自定义的输出流 CompressionResponseWrapper 类就是装饰器设计模式的一个应用。CompressionResponseWrapper类实现如下:
public class CompressionResponseWrapper extends HttpServletResponseWrapper {
private HttpServletResponse response;
public CompressionResponseWrapper(HttpServletResponse response) {
super(response);
this.response = response;
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
System.out.println("在这里可对输出流进行定制操作,例如进行压缩,返回压缩后的新的输出流");
return response.getOutputStream();
}
}
这里CompressionResponseWrapper类相当于上述装饰器设计模式类图中的ConcreteDecorateA类,HttpServletResponse类则相当于待装饰的接口。CompressionResponseWrapper类还可以再被装饰添加其他功能,这就是装饰器设计模式的强大之处。
装饰器设计模式初探及Java中实际应用举例的更多相关文章
- java设计模式之装饰器模式以及在java中作用
在JAVA I/O类库里有很多不同的功能组合情况,这些不同的功能组合都是使用装饰器模式实现的,下面以FilterInputStream为例介绍装饰器模式的使用 FilterInputStream和F ...
- 11 IO流(八)——装饰器设计模式,Filter装饰流
声明:本文部分图片及内容引用自:https://www.cnblogs.com/qiumingcheng/p/5219631.html java装饰器设计模式 举一个形象的例子,人可以说话,而扩音器可 ...
- java 实现装饰器设计模式
package com.gylhaut.base; /** * 装饰器 * 类与类之间的关系 * 1.依赖:形参(局部变量) * 2.关联:属性 * 聚合 属性 整体和部分 不一致的生命周期 人和手 ...
- 设计模式学习笔记——java中常用的设计模式
单例设计模式(Singleton Pattern) 观察者模式(Observer Pattern) 工厂模式(Factory Pattern) 策略模式(Strategy Pattern) 适配器模式 ...
- .NET中的装饰器设计模式
- 适配器设计模式初探(Java实现)
本篇随笔主要介绍Java实现设配器设计模式. 先来看下待解决的问题: (图片转自http://blog.csdn.net/jason0539) 由上图的情况可知,欧洲壁式插座只有三足插口,如果我们想要 ...
- Java中MySQL事务处理举例
实例(以sql语句中的insert语句为例) import java.sql.Connection; import java.sql.DriverManager; import java.sql.Pr ...
- [译]Java 设计模式之装饰器
(文章翻译自Java Design Pattern: Decorator – Decorate your girlfriend) 1.装饰模式的来历 让我们假设你在寻找一个女朋友.有来自像没美国中国日 ...
- C#中的 Attribute 与 Python/TypeScript 中的装饰器是同个东西吗
前言 最近成功把「前端带师」带入C#的坑(实际是前端带师开始从cocos转unity游戏开发了) 某天,「前端带师」看到这段代码后问了个问题:[这个是装饰器]? [HttpGet] public Re ...
随机推荐
- Swing编程---添加背景图片的方法
总结:看下我的运行图片.这个图片很重要.很能说明问题.它的frame就是一个小图片.就是背景.么手贱把它放大. 在微软的操作系统上,你放多大,窗口就有多大,你看到背景就成了小图片,就会误以为不是背景. ...
- Java-API-Package:org.springframwork.transaction.annotation
ylbtech-Java-API-Package:org.springframwork.transaction.annotation 1.返回顶部 1. @NonNullApi @NonNullFie ...
- 【转】ruby中nil?, empty? and blank?的选择
In Ruby, you check with nil? if an object is nil:article = nil article.nil? # => true empty? chec ...
- java集合类(2)
java集合的主要分为三种类型:JAVA集合位于 java.util包 Set(集) List(列表) Map(映射) arrays函数, equals():比较两个array是否相等. fill() ...
- flask 电影系统(2)
标签,电影,上映预告数据模型设计 标签数据类型 id:编号 name:标题 movies:电影外键关联 addtime:创建时间 定义电影数据模型 id:编号 title:电影标题 url:电影地址 ...
- ffmpeg/ffplay源码剖析笔记<转>
转载:http://www.cnblogs.com/azraelly/ http://www.cnblogs.com/azraelly/archive/2013/01/18/2865858.html ...
- JS写一个简单的程序,输入两个整数,打印这两个数的和,差,积,余数
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Access restriction required library rt.jar
在JAVA项目开发中,使用到了BASE64Decoder,但编辑运行时却会出现以下错误:Access restriction required library rt.jar,这里就详细的说明一下如何解 ...
- Android LRUCache
package android.util; import java.util.LinkedHashMap; import java.util.Map; /** * A cache that holds ...
- 第3章_Java仿微信全栈高性能后台+移动客户端
当服务器构建完毕并且启动之后,我们通过网页URL地址就可以访问这台服务器,并且服务器会向网页输出Hello Netty这样几个字. Netty有三种线程模型:单线程.多线程.主从线程.Netty官方推 ...