当前位置: 首页 > news >正文

java设计模式_代理模式

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

今天我就写写代理模式,包括静态代理和动态代理。同时也提出我在写代理模式的时候碰到的问题,即在写静态代理的时候,发现了静态代理模式很像装饰者模式,都是通过实现接口和组合的方式来实现,只是真实接口实现类的存在方式不同,静态代理是在代理类里面直接new 一个接口实现类,而装饰者模式是通过构造函数参数传递到装饰类。

百度了一下,下面的观点我是比较认可的:

装饰模式:以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案;
代理模式:给一个对象提供一个代理对象,并有代理对象来控制对原有对象的引用
装饰模式应该为所装饰的对象增强功能;代理模式对代理的对象施加控制,并不提供对象本身的增强功能。

两者的key point不一样。一个突出扩展功能,一个突出控制对原有对象的引用。

说了这么多了,该上代码了。

接口:

package com.wangbiao.my.proxy;
/**
 * @author wangbiao
 * @date and time May 22, 2014 5:40:30 PM 
 * 
 */
public interface User {
    
    public void printName(String name);

}

实现类:

package com.wangbiao.my.proxy;


/**
 * @author wangbiao
 * @date and time May 22, 2014 5:41:29 PM 
 * 
 */
public class UserImp implements User {

    @Override
    public void printName(String name) {
        System.out.println(name);
    }

}


静态代理:

package com.wangbiao.my.proxy;
/**
 * @author wangbiao
 * @date and time May 22, 2014 11:17:27 PM 
 * 
 */
public class StaticProxy implements User{

    private User user = new UserImp();
    
    @Override
    public void printName(String name) {
        
        // TODO before invoke method
         user.printName(name);
        // TODO after invoke method
    }

}


装饰者模式:

package com.wangbiao.my.proxy;
/**
 * @author wangbiao
 * @date and time May 22, 2014 11:17:27 PM 
 * 
 */
public class DecoraterClass  implements User{

    private User user;
    
    public DecoraterClass() {
        // TODO Auto-generated constructor stub
    }
    
    public DecoraterClass(User user) {
        this.user = user;
    }
    
    @Override
    public void printName(String name) {
        
        // TODO before invoke method
         user.printName(name);
        // TODO after invoke method
    }

}

   

    动态代理(用的是java jdk6 自带的动态代理),也有其他的实现方式,CGLIB和JAVAASSIST.

    对于动态代理,个人认为运用的最经典的地方是AOP。

package com.wangbiao.my.proxy;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author wangbiao
 * @date and time May 22, 2014 5:32:34 PM 
 * 
 */
public class Test {
    
    
    public static Object getProxyInstance(final Object realObject) throws Exception{
        
    Class clazz = Proxy.getProxyClass(User.class.getClassLoader(), new Class[]{User.class});
    Constructor[]  cons = clazz.getConstructors();
    System.out.println(cons);
    System.out.println(cons[0].getName());
    Object obj = cons[0].newInstance(new InvocationHandler() {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
        System.out.println("begin invoke method");
        System.out.println("method name is : "+method.getName());
        Object retObj = method.invoke(realObject, args);
        System.out.println("end invoke method");
        return retObj;
        }
    });
        return obj;
    
    
    // get the proxy object
    /*
      Object obj = Proxy.newProxyInstance(User.class.getClassLoader(),
     
            new Class[]{User.class},
            new InvocationHandler() {
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            System.out.println("begin invoke method");
            System.out.println("method name is : "+method.getName());
            Object retObj = method.invoke(realObject, args);
            System.out.println("end invoke method");
            return retObj;
        }
    });    
        return obj;
    */
    }
    

    public static void main(String[] args) throws Exception {
        
        User user = (User) getProxyInstance(new UserImp());
        System.out.println(user.getClass().getName());//$Proxy0
        user.printName("dynamic proxy study");
        
    }
    
    
    
}


转载于:https://my.oschina.net/u/617909/blog/267907

相关文章:

  • Gradle 取相对路径
  • VIEW登陆故障解决办法。
  • 有规律的坚持写文章有多难?
  • log4j+commons-logging结合使用
  • java每日小算法(20)
  • Dive into Python
  • ORA-00600错误及其解决方案
  • java-第二章-华氏温度转摄氏温度
  • jprofile学习资料
  • OpenGL基础图形编程 - 复杂物体建模
  • 几道经典C语言面试题
  • Android经典三部曲:
  • 编程语言中的除法
  • Win7_x64下卸载Oracle11g
  • 用jQuery解决弹出层的问题
  • [PHP内核探索]PHP中的哈希表
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • 345-反转字符串中的元音字母
  • ECMAScript6(0):ES6简明参考手册
  • PHP面试之三:MySQL数据库
  • Sequelize 中文文档 v4 - Getting started - 入门
  • XML已死 ?
  • 安装python包到指定虚拟环境
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 树莓派 - 使用须知
  • 线性表及其算法(java实现)
  • Hibernate主键生成策略及选择
  • ​ArcGIS Pro 如何批量删除字段
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • ​香农与信息论三大定律
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • #laravel 通过手动安装依赖PHPExcel#
  • #在 README.md 中生成项目目录结构
  • (arch)linux 转换文件编码格式
  • (阿里云万网)-域名注册购买实名流程
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (六)vue-router+UI组件库
  • (未解决)macOS matplotlib 中文是方框
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • .NET HttpWebRequest、WebClient、HttpClient
  • .net web项目 调用webService
  • .NET 指南:抽象化实现的基类
  • .Net程序帮助文档制作
  • /bin/rm: 参数列表过长"的解决办法
  • @media screen 针对不同移动设备
  • [ 蓝桥杯Web真题 ]-Markdown 文档解析
  • [2010-8-30]
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
  • [20181219]script使用小技巧.txt
  • [ActionScript][AS3]小小笔记
  • [AIGC codze] Kafka 的 rebalance 机制
  • [Angular] 笔记 20:NgContent
  • [Asp.net MVC]Bundle合并,压缩js、css文件
  • [BUG]vscode插件live server无法自动打开浏览器