设计模式:专门为解决某一类问题,而编写的固定格式的代码。
装饰者模式
一、职责
1、动态的为一个对象增加新的功能
2、装饰模式是一种用于替代继承的技术,无需通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。
二、实现细节
1、Component抽象构件角色:
真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互。
2、ConcreteComponent 具体构件角色(真实对象):
io流中的FileInputStream、FileOutputStream
3、Decorator装饰角色:
持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象。这样,就能在真实对象调用前后增加新的功能。
4、ConcreteDecorator具体装饰角色:
负责给构件对象增加新的责任。
三、开发中使用的场景
1、 Servlet API 中的request
Servlet API 中提供了一个request对象的Decorator设计模式的默认实现类HttpServletRequestWrapper,HttpServletRequestWrapper类,增强了request对象的功能。
类图关系如下:
应用:解决get提交的乱码问题
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class CharacterEncoding implements Filter{
public void destroy() {
}
public void init(FilterConfig arg0) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
chain.doFilter(new HttpServletRequestWrapper((HttpServletRequest)request){
public String getParameter(String name) {
if("get".equals(this.getMethod().toLowerCase())) {
String value = super.getParameter(name);
if(value != null)
try {
return new String(value.getBytes("iso-8859-1"),"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return super.getParameter(name);
}
}, response);
}
}
2、connection中的close()
重写close方法,使connection用完后重新添加到连接池中去,而不是关闭资源:
MyConnection:(装饰者)
public class MyConnection implements Connection{
//1、存放Connction的另一个实现类
private Connection conn;
private LinkedList<Connection> list;
//2、构造方法,吧Connection的另一个实现类作为成员变量写入
public MyConnection(Connection conn,LinkedList<Connection> list) {
this.conn = conn;
this.list = list;
}
//3、重写prepareStatement(String sql)方法
public PreparedStatement prepareStatement(String sql) throws SQLException {
return conn.prepareStatement(sql);
}
//4、重写close()方法
public void close() throws SQLException {
list.add(conn);
}
。。。。。。。。。。。其他方法
}
3、IO中输入流和输出流设计
(1)InputStream:
关系类图:
- inputStream中有个read()抽象方法
- 具体实现类中都实现了该类
- FilterInputStream中有一个InputStream的引用,用来存被装饰对象
- 具体装饰类都装饰了read()方法
(2)OutputStream:
OutputStream的设计类似于inputStream:
- OutputStream抽象类中有抽象方法write(int)
- FilterOutputStream中有引用OutputStream用于存放被装饰的类
- 其继承类都装饰了write(int)方法
4、其他应用
Swing包中图形界面构件功能
Struts2中,request,response,session对象的处理