什么是代理模式(Proxy)?应用场景是什么?

代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。
怎么理解这个概念呢?就比如说我会开车,我现在要出门去买东西,结果我车开不出来了,而且我倒车入库技术很差,咋办呢?我是不是要找一个厉害的司机(代理)呢?这个时候就可以用代理模式的思想,如何设计呢?
既然我和司机都会开车,那么就可以把开车这个抽象为一个接口,具体实现如下:

/**  静态代理  **/
public interface Driver {
	void drive();
}
// 目标对象
public class Wo implements Driver {

	@Override
	public void drive() {
		System.out.println("我只会开车,不会侧方和倒库哇。。");
	}
	
}


// 代理对象==和目标对象实现相同的接口
public class SiJi implements Driver {
	// 接收目标对象,以便调用方法
	private Wo wo;
	
	public SiJi(Wo wo) {
		super();
		this.wo = wo;
	}
	
	// 对目标对象的方法进行功能扩展
	@Override
	public void drive() {
		System.out.println("司机从车库里把车开出来");
		wo.drive(); //
		System.out.println("司机把车停好,走了!");
	}
	
}
/**
 * 测试类
 */
public class Test {
	public static void main(String[] args) {
		// 目标对象
		Wo target = new Wo();
		// 代理对象
		SiJi proxy = new SiJi(target);
		// 执行的是代理的方法
		proxy.drive();
	}
}

Proxy代理模式简单说即是在不改变源码的情况下,实现对目标对象的功能扩展。所以说穿了,代理就是真实对象的代表,所以代理对象需要特意实现包含目标对象的方法,假使代理对象中只是简单地对driver()方法做了另一种实现而没有包含目标对象的方法,也就不能算作代理模式了,所以这里的包含是关键。

上述这种自己实现的代理模式,在代理模式的划分中,被归为静态代理模式,它有一个很明显的缺点:代理对象必须提前写出,如果接口发生改变,那么代理类和代理对象的代码也要进行改变。

那么,什么是动态代理模式呢?
动态代理模式就是使用Java内建的对代理模式支持的功能来实现的代理,动态代理目前只能代理接口,而且实现机制是依靠Java的反射和动态生成class的技术来动态生成被代理的接口的实现对象(动态代理是实现AOP的重要手段)。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * 接口和被代理对象不变
 * 重新改造代理对象类,改为动态代理模式
 *
 */
public class SiJi {
	// 目标对象(也叫做被代理对象)
	private Driver dri = null;

	public SiJi(Driver dri) {
		this.dri = dri;
	}

	public Driver createStarProxy() {
		return (Driver) Proxy.newProxyInstance(SiJi.class.getClassLoader(), dri.getClass().getInterfaces(),
				new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						// 代理动作
						String methodName = method.getName();
						if (methodName.equals("drive")) {
							System.out.println("司机从车库里把车开出来");
							Object info = method.invoke(dri, args);// 方法返回的信息
							System.out.println("司机把车停好,走了!");
							return info;
						} else {
							System.out.println("你没有叫司机啊!!");
						}
						return null;
					}
				});
	}

}
public class Test {
	public static void main(String[] args) {
		// 目标对象
		Driver target = new Wo();
		
		// 注入被代理对象
		SiJi proxy = new SiJi(target);
		//创建被代理对象
		Driver targetProxy = proxy.createStarProxy();
		// 执行的是代理的方法
		targetProxy.drive();
	}
}


>>>>>输出<<<<<
司机从车库里把车开出来
我只会开车,不会侧方和倒库哇。。
司机把车停好,走了!

代理模式说穿了就是创建一个对象去代表真实对象,所以客户端得到这个代理对象的时候其实并不知道这个对象是真是假,相当于代理对象成了中转,所以代理模式的应用场景总结有:

当我们需要使用的对象很复杂或者需要很长时间去构造时,就可以使用代理模式(Proxy)。

例如:如果构建一个对象很耗费时间和计算机资源,代理模式(Proxy)允许我们控制这种情况,直到我们需要使用实际的对象。

一个对象,比如一幅很大的图像,需要载入的时间很长  
一个需要很长时间才可以完成的计算结果,并且需要在它计算过程中显示中间结果
一个存在于远程计算机上的对象,需要通过网络载入这个远程对象则需要很长时间,特别是在网络传输高峰期
一个对象只有有限的访问权限,代理模式(Proxy)可以验证用户的权限
使用代理模式来将由一系列无关逻辑组合在一起的代码进行解耦合,比如业务代码中的日志代码就可以在代理中进行,典型的动态代理应用就是spring的AOP。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值