代理模式(Proxy Pattern)(一):代理模式介绍

一、意图


为其他对象提供一种代理以控制对这个对象的访问。



二、适用性



使用代理模式的常见的重要情况有:


1) 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。比如:你可以将一个在世界某个角落一台机器通过代理假象成你局域网中的一部分。

2) 虚拟(Virtual)代理:根据需要将一个资源消耗很大或者比较复杂的对象延迟的真正需要时才创建。比如:如果一个很大的图片,需要花费很长时间才能显示出来,那么当这个图片包含在文档中时,使用编辑器或浏览器打开这个文档,这个大图片可能就影响了文档的阅读,这时需要做个图片Proxy 来代替真正的图片。

3) 保护(Protect or Access)代理:控制对一个对象的访问权限。比如:在论坛中,不同的身份登陆,拥有的权限是不同的,使用代理模式可以控制权限。

4) 智能引用(Smart Reference)代理:提供比对目标对象额外的服务。比如:纪录访问的流量,提供一些友情提示等等。


还有其他情况也较为常见:

1)写时复制(Copy-on-Write)代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。

2)缓存(Cache)代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。

3)防火墙(Firewall)代理:保护目标,不让恶意用户接近。

4)同步(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。





三、组成



——抽象角色(Subject):声明真实对象和代理对象的共同接口,这样,在任何使用真实对象的地方都可以使用代理对象。


——代理角色(Proxy):代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时代理对象可以在执行真实对象操作时,附加其他的操作,控制对真实对象的访问。


——真实角色(RealSubject):代理角所代表的真实对象,是我们最终要引用的对象。




四、结构




五、简单实现



1.抽象角色(Subject)

public interface Subject
{
	public void request();
}


2.真实角色(RealSubject)

public class RealSubject implements Subject
{
	@Override
	public void request()
	{
		System.out.println("from real subject");
	}

}

3.代理角色(Proxy)

public class Proxy implements Subject
{
	Subject realSubject;

	@Override
	public void request()
	{
		this.preRequest();// 控制访问
		if (this.realSubject == null)
			this.realSubject = new RealSubject();
		this.realSubject.request();
		this.afterRequest();
	}

	// 加入新的操作
	public void preRequest()
	{
		System.out.println("pre request");
	}

	public void afterRequest()
	{
		System.out.println("after request");
	}
}

4.测试

public class Client
{
	public static void main(String[] args)
	{
		Subject subject = new Proxy();
		subject.request();
	}
}



六、其他


1.使用代理模式创建代理对象,让代理对象控制对真实对象的访问,被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象。远程代理管理客户和远程对象之间的交互,虚拟代理控制访问实例化开销大的对象,保护代理基于调用者控制对象方法的访问。


2.与其他模式比较:装饰者 模式为对象加上新的行为或责任,而代理模式则是控制访问,并不提供对象本身的增强功能;适配器模式是改变所考虑的对象的接口,而代理模式并不能改变所代理的对象的接口;


3.远程代理(Remote Proxy)不包含对实体的直接引用,而只是一个间接引用,如“主机I D,主机上的局部地址”。虚拟代理(Virtual Proxy)开始的时候使用一个间接引用,例如一个文件名,但最终将获取并使用一个直接引用。


3.如果按照上述方法使用代理模式,那么真实角色必须是事先存在的,并且将其作为代理对象的内部属性。但是,实际使用时,一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀(就像装饰者模式的弊端一样),此外,如果事先不知道真实角色呢,将如何代理?这些问题可以通过java的动态代理类来解决(相对于java的动态代理,上面的代理方式可称为静态代理)。



转载请注明出处:http://blog.csdn.net/jialinqiang/article/details/8949147

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值