更好的理解装饰设计模式和代理设计模式
来源:互联网 发布:次世代软件 编辑:程序博客网 时间:2024/05/16 04:37
更好的理解装饰设计模式和代理设计模式
最近在一个小项目中,出现装饰模式和代理模式。有时感觉它们很像。。好好整理了下,发现还是。。。
下面通过这个过滤器看下装饰类是如何用的?
import java.io.IOException;import java.util.Map;import java.util.Map.Entry;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 EncodingFilter implements Filter {private String encode=null;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {//拿到配置文件中的编码值this.encode=filterConfig.getServletContext().getInitParameter("encode");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {response.setContentType("text/html;charset="+encode);chain.doFilter(new MyHttpServletRequest((HttpServletRequest) request), response);}//装饰类,用来改变不某些不想要的方法,装饰类,装饰request对象,改造和获取请求参数相关的三个方法,改造成获取有乱码的值,解决乱码后返回// 这样一来,包装过后的request,虽然内部还是乱码,但是通过方法获取时,是解决过后没有乱码的值class MyHttpServletRequest extends HttpServletRequestWrapper{private HttpServletRequest request=null;private boolean EncodehasNode=true;//构造方法public MyHttpServletRequest(HttpServletRequest request) {super(request);this.request=request;}//复写三个方法 *//** * Returns a java.util.Map of the parameters of this request. Request * parameters are extra information sent with the request. For HTTP * servlets, parameters are contained in the query string or posted form * data. * * @return an immutable java.util.Map containing parameter names as keys and * parameter values as map values. The keys in the parameter map are * of type String. The values in the parameter map are of type * String array. *//*//这三个方法是ServeltRequest接口身上的抽象方法@Overridepublic Map<String, String[]> getParameterMap() {try {if(request.getMethod().equals("POST")){//--POST提交,一行代码解决乱码,返回request.setCharacterEncoding(encode);//return getParameterMap();return request.getParameterMap();}else if(request.getMethod().equals("GET")){//--GET提交获取有乱码的Map,手动编解码解决返回Map<String, String[]> map=request.getParameterMap();if(EncodehasNode){for(Entry<String, String[]> entry: map.entrySet() ){String [] vs=entry.getValue();for(int i=0;i<vs.length;i++){//解码//底层解码原理:/***static char[] decode(String charsetName, byte[] ba, int off, int len) throws UnsupportedEncodingException { StringDecoder sd = deref(decoder); String csn = (charsetName == null) ? "ISO-8859-1" : charsetName; if ((sd == null) || !(csn.equals(sd.requestedCharsetName()) || csn.equals(sd.charsetName()))) { sd = null; try { Charset cs = lookupCharset(csn); if (cs != null) sd = new StringDecoder(cs, csn); } catch (IllegalCharsetNameException x) {} if (sd == null) throw new UnsupportedEncodingException(csn); set(decoder, sd); } return sd.decode(ba, off, len); } ****/vs[i]=new String(vs[i].getBytes("iso8859-1"),encode);}}//执行完第一次后,就把它置为false,因为第一次就都编译好了EncodehasNode=false;}return map;}else{//其他格式,就返回return getParameterMap();}} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);}}@Overridepublic String getParameter(String name) {//调用getParameterValues得到第0位String vs[]=getParameterValues(name);//判断是名字是不是为空return vs ==null ? null:vs[0];}@Overridepublic String[] getParameterValues(String name) {return getParameterMap().get(name);}}@Overridepublic void destroy() {}}
装饰者模式的特点为:
1、装饰者和被装饰者对象有相同的超类型。
2、你可以用一个或多个装饰者包装一个对象
3、那么我们知道装饰和被装饰者有相同的超类型,所以在任何须要原始对象(被包装)的对象场合,可以用装饰过的对象代替它。
4、装饰者可以在所委托被装饰者的行为之前/或之后,加上自己行为,以达到特定的目的。
5.对象可以在任何时候被装饰
代理模式:为另一个对象提供一个替身或占位符以控制对这个对象的访问。
代理模式的变种相当多。如动态代理,虚拟代理,保护代理,远程代理。。
我们的EJB技术就是用到了代理模式。
接口:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>package bean;import javax.ejb.Remote;@Remotepublic interface LoginRemote {public boolean login(String id, String pwd);}</strong></span>实例类:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>import java.util.Iterator;import javax.annotation.Resource;import javax.ejb.Remote;import javax.ejb.Stateless;import javax.persistence.EntityManager;import javax.persistence.PersistenceContext;import javax.persistence.Query;import javax.sql.DataSource;import model.User;@Stateless@Remote(LoginRemote.class)public class Login implements LoginRemote {@PersistenceContextprotected EntityManager em;public Login() {}@Resource(mappedName = "java:jboss/myDataSource")DataSource myDb;@Overridepublic boolean login(String id, String pwd) {Query query = em.createQuery("select u from User u");Iterator iter = query.getResultList().iterator();System.out.println(iter.hasNext());while(iter.hasNext()) {User user = (User)iter.next();if(id.equals(user.getId()) && pwd.equals(user.getPwd())) {return true;}}return false;}}</strong></span>
测试类,实际上也就是客户端,通过调用接口,来达到实现的目的。。
<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>import bean.Login;public class Test {public static void main(String args) {new Login().login("haha", "haha");}}</strong></span>
客户端通过调用
远程接口或本地接口。。来达到实现接口的方法。。这种被称为远程代理。就如同我们开时开3389远程
端口一样。通过远程桌面进行服务器进行访部操作。远程桌面就是起到了一个代理的作用。
远程代理
远程代理可以为作为另个JVM上对象的本地代表,调用代理的方法,会被代理利用网络转发到远程执行,并且结果会
通过网络返回给代理。。再由代理将结果转给客户。
虚拟代理
虚拟代理作为开销大的对象的代表。虚拟代理经常直到我们真正需要一个对象的时候才创建它。当对象在创建前和创建中时由虚拟代理来扮演对象的替身,对象创建后,代理就会将请求直接委托给对象。。
核心对比:代理很像装饰者,很容易让大家以为是用一个对象把另一个包起来。然后委托一个实现方法。如动态代理是给IncovationHandler接口。通过回调,在invoke方法中进行修改你方法达到你想要的。我在这里主要理解的是。。它们虽然你,但是目的不同,因为装饰者为对象境加行为,而代理是控制对象的访问。你可能想到的是:显示在”加载中“消息,难道不是在增加行为,从一定程度上说,这的确可以算是,但是,更重要的是,代理是控制对某一个你要想改造的方法的访问,可以参考(我的另一篇博文(通个一个工具类更深理解动态代理),如何控制访问呢?代理将用户从改造的方法解耦了,就是一种两全其美的方法,用到这个方法时,通过代理是一种情况,不用到代理时,照样能很好的实现它原来的作用。。
我们给用户使用的是代理,而不是直正的对象。
通常来说。工厂也能做到这一点,只要你提供原料在工厂中实例化,返加主题,就变了。不同的原料
返回的主题也不同。代理同样也能达到这种效果。用户不知道也不在乎他使用的是代理还是真实的对象。
写到这里,突然又想起一个家伙。适配器。。因为不想一下代理和适配器都是挡在其他对象的前面,并负责请求转以给它们适配器会改变对象适配器的接口。而代理是实现相同的接口。打个比方,同样买到香港的电脑,我们知道香港的插孔和大陆的插孔是不一样的。可以通过代理去买。也可以直接在海淘然后发货给你。代理会按照你的要求(接口),买成大陆通用的版本,而香港卖家可能并不知道,你的具体需求,因为全世界这么多买家,他可能只会给你一套通用的插口。可以转换各个国家具体的插孔。这样转换头就是一个适配器。。
0 0
- 更好的理解装饰设计模式和代理设计模式
- 设计模式-代理模式和装饰模式
- 装饰设计模式和代理设计模式的区别
- 设计模式--代理模式--以及和装饰模式的区别
- 装饰设计模式的理解。
- 装饰设计模式的理解
- 代理模式和装饰模式的理解
- 再看设计模式:代理、装饰和适配器
- 设计模式:装饰器和代理
- 设计模式之装饰设和代理设计模式
- 设计模式学习之装饰模式和代理模式
- 设计模式之代理模式,装饰模式和继承
- 设计模式之代理模式和装饰者模式
- 装饰设计模式与代理设计模式的异同
- 设计模式(代理模式、装饰模式)
- 设计模式之--装饰模式与代理模式的区别
- 【设计模式】 装饰模式与代理模式的对比
- 设计模式,我理解的代理模式
- 2014.8.2模拟赛【打地鼠游戏】
- 关于Android解析XML
- Codeforces 453A Little Pony and Expected Maximum(期望)
- mongoDB 管理常用命令
- Android 自定义ViewGroup 实战篇 -> 实现FlowLayout
- 更好的理解装饰设计模式和代理设计模式
- 使用volley实现简单的操作,json传输,网络图片显示
- 多线程死锁
- Struts2.x文件上传和下载
- 最新的Xcode6_beta_4下载
- 读写锁的特性
- 在O(1时间删除链表节点
- rt5350 捕获sn9c291 ov9712 模块jpeg图片效果
- Codeforces 453B Little Pony and Harmony Chest(状压)