linkin大话设计模式--代理模式
代理模式是一种应用非常广泛的设计模式,当客户端代码需要调用某个对象的时候,客户端并不关心是否可以准确的得到这个对象,他只要一个能够提供该功能的对象而已,此时我们就可以返回该对象的代理。总而言之,客户端代码不能或者不想直接访问被调用对象,服务器这段额外的建立一个代理对象返回给客户端使用,那么这种设计方式就是代理模式。
自从JDK的版本到1.3以后,java语言通过java.lang.reflect库中,提供了三个类来直接支持代理模式。分别是:Proxy,InvocoationHandler和Method。Proxy类使得设计师能够在运行时间创建代理对象,当系统有了一个代理对象后,对源对象的方法调用会首先被分派给一个调用处理器(InvocationHandler)//接口,InvocationHandler接口中有一个invoke()方法,程序可以在调用处理器的invoke方法中截获这个调用,进行额外的操作。
创建动态代理对象的步骤:
1.指明一系列的接口来创建一个代理对象
2.创建一个调用处理器(InvocationHandler)对象
3.将这个代理指定为某个其他对象的代理对象
4.在调用处理器的invoke方法中采取代理,一方面将调用传递给真实对象,另一方面执行各种需要做的操作。
其中代理模式在hibernate和spring中都有应用,下面代码模拟hibernate中的懒加载。
代码如下:
<strong><span style="font-size:14px;">//代理和实际对象都要实现的接口
interface Image{
//随便定义一个方法
public void show();
} //模拟客户端使用的代理
class ImageProxy implements Image{ private Image image; public ImageProxy(Image image) {
super();
this.image = image;
} @Override
public void show() {
//加入自己的代码逻辑 在用到这个show方法的时候 才会去真正的创建那个实实在在的对象
if(null == image){
image = new BigImage();
}
image.show();
} } //实际的对象
public class BigImage implements Image{ public BigImage(){
try {
Thread.sleep(5000);
System.out.println("BigImage...");
} catch (InterruptedException e) {
e.printStackTrace();
}
} @Override
public void show() {
System.out.println("梦似烟花心似水,同学少年不言情。。。");
} public static void main(String[] args) {
//直接使用真正的对象 在new那个对象的时候会有的5000秒的延迟
long stateTime1 = System.currentTimeMillis();
Image image1 = new BigImage();
System.out.println(System.currentTimeMillis() - stateTime1+"\n"); //使用代理,直接很快的创建了一个代理对象,在真正使用到对象的show方法的时候 才会有5000秒的延迟
long stateTime = System.currentTimeMillis();
Image image = new ImageProxy(null);
System.out.println(System.currentTimeMillis() - stateTime);
image.show(); } } </span></strong>
在spring中也使用了代理模式,其中spring的AOP就是代理模式的一个典型应用。
<strong><span style="font-size:14px;">import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; //java动态代理 代理对象和被代理对象都要实现的接口
interface Dog{
public void info(); public void run();
} //模拟事务管理器
class TxUtil{ public void beginTx(){
System.out.println("...模拟事务开始...");
} public void endTx(){
System.out.println("...模拟事务结束...\n");
}
} //java动态代理的关键之一,InvocationHandler的实现类,这个类的invoke方法将成为最后代理对象方法的实现
class LinkinInvocationHandler implements InvocationHandler{
//需要被代理的对象
private Object target; public void setTarget(Object target) {
this.target = target;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
TxUtil txUtil = new TxUtil();
txUtil.beginTx();
//方法的反射 需要被代理的对象作为主调来调用方法
Object result = method.invoke(target, args);
txUtil.endTx();
return result;
} } //模拟一个获得代理对象的工厂
class LinkinProxyFactory{
public static Object getProxyInstance(Object target){
LinkinInvocationHandler hander = new LinkinInvocationHandler();
hander.setTarget(target);
//改天复习下反射 注意下面方法的返回值
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), hander);
}
} //被代理对象
public class MyDog implements Dog{ @Override
public void info() {
System.out.println("忠犬8公...");
} @Override
public void run() {
System.out.println("很忠诚的...");
} public static void main(String[] args) {
//获得一个被代理对象
MyDog myDog = new MyDog();
//以被代理对象作为参数获得一个代理对象 一般情况下编译类型都是接口
Dog myDogProxy = (Dog) LinkinProxyFactory.getProxyInstance(myDog);
myDogProxy.info();
myDogProxy.run();
} }</span></strong>
linkin大话设计模式--代理模式的更多相关文章
- linkin大话设计模式--常用模式总结
linkin大话设计模式--常用模式总结 一,常用设计模式定义 Abstract Factory(抽象工厂模式):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. Adapter( ...
- linkin大话设计模式--建造模式
linkin大话设计模式--建造模式 建造模式是对象的创建模式,可以讲一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象. 建造模式的结构: 抽象建造者 ...
- linkin大话设计模式--模板方法模式
linkin大话设计模式--模板方法模式 准备一个抽象类,将部分逻辑以具体方法的形式实现,然后申明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不 ...
- linkin大话设计模式--桥接模式
linkin大话设计模式--桥接模式 桥接模式是一种结构化模式,他主要应对的是:由于实际的需要,某个类具有2个或者2个以上维度的变化,如果只是使用继承将无法实现功能,或者会使得设计变得相当的臃肿.我们 ...
- linkin大话设计模式--门面模式
linkin大话设计模式--门面模式 随着系统的不断改进和开发,他们会变得越来越复杂,系统会生成大量的类,这使得程序的流程更加难以理解.门面模式可以为这些类提供一个简易的接口,从而简化访问这些类的复杂 ...
- linkin大话设计模式--策略模式
linkin大话设计模式--策略模式 Strategy [ˈstrætədʒi] 策略 策略模式用于封装系列的算法,这些算法通常被封装在一个称为Context的类中,客户端程序可以自由的选择任何一种 ...
- linkin大话设计模式--命令模式
linkin大话设计模式--命令模式 首先考虑一种应用情况,某个方法需要完成某一个功能,这个功能的大部分功能已经确定了,但是有可能少量的步骤没法确定,必须等到执行这个方法才可以确定. 也就是说,我们写 ...
- 大话设计模式--代理模式 proxy
1. 代理模式: 为其他对象提供一种代理以控制这个对象的访问. 代理模式使用场合: a. 远程代理, 为一个对象在不同的地址空间提供局部代理,隐藏一个对象存在于不同地址空间的事实.如.net中WebS ...
- linkin大话设计模式--单例模式
linkin大话设计模式 开文前先弱弱的问一句:什么是设计模式?我在研究java2ee的时候有研究过,在学js的时候也有看到.设计模式的概念最早源于建筑设计大师<建筑的永恒算法>一书,它表 ...
随机推荐
- HTML之前端操作div标签布局
事例图片: div元素是用于分组HTML元素的块级元素 上图代码示例如下: <!DOCTYPE html> <html lang="en"> <hea ...
- msgpack库的神奇用法
一般来说,我们会把头部和实际消息分开定义,因为内部工作的worker之间发送消息有些额外的字段,这些字段不属于实际的消息.这时候我们会把worker消息中一个字段定义为interface{}或者obj ...
- asp.net mvc 5 蛋疼的问题
看图,debugger显示匹配路径没有错. html开源码看 显示没有实现IController. 然而我的确实现了. 关闭vs 重启
- java指令重排序的问题
转载自于:http://my.oschina.net/004/blog/222069?fromerr=ER2mp62C 指令重排序是个比较复杂.觉得有些不可思议的问题,同样是先以例子开头(建议大家跑下 ...
- Python 集合 深浅copy
一,集合. 集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 去重,把一个列表变成集合,就自动去重了. ...
- 视觉slam十四讲习题ch3-6
题目回顾: 一般解线性方程Ax=b有哪几种做法?你能在Eigen中实现吗? 解: 线性方程组Ax = b的解法 : 1.直接法:(1,2,3,4,5) 2.迭代法:如Jacobi迭代法(6) 其中只有 ...
- JAVA实用案例之文件导出(JasperReport踩坑实录)
写在最前面 想想来新公司也快五个月了,恍惚一瞬间. 翻了翻博客,因为太忙,也有将近五个多月没认真总结过了. 正好趁着今天老婆出门团建的机会,记录下最近这段时间遇到的大坑-JasperReport. 六 ...
- 4395: [Usaco2015 dec]Switching on the Lights
每次到达一个点,或者点亮一个房间的灯的时候,检查一下它四周的点能否走. 一开始看错题了..要求的是最多能开多少房的灯. #include<cstdio> #include<iostr ...
- CF 610E. Alphabet Permutations
题目:http://codeforces.com/problemset/problem/610/E 如果存在c1,c2在原串相邻且在询问串中c1在c2前面的话,把它们在原串出现次数加起来记作sum,那 ...
- hdu_1029_hash/map
http://acm.hdu.edu.cn/showproblem.php?pid=1029 太水了,一次过,直接上代码吧,只想说最愚蠢的hash都要比map快! #include<cstdio ...