Java设计模式--代理模式

一、简介

1.1 模式定义

给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫做Proxy或Surrogate,它是一种对象结构型模式。

1.2 适用场景

根据代理模式的使用目的,常见的代理模式有一下几种类型。
1) 远程代理:为一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以是在同一台主机中, 也可是在另一台主机中,远程代理又叫做大使。
2)虚拟代理:如果需要创建一个资源消耗较大的而对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
3)Copy-on-Write:它是虚拟代理的一种,把复制(克隆)操作延迟到只在客户端正在需要时才执行。一般来说,对象的深克隆是一个开销较大的操作,Copy-on-Write代理可以让这个操作延迟,只有对象呗用到的时候才被克隆。
4)保护代理:控制一个对象的访问,可以给不同的用户提供不同级别的使用权限。
5)缓冲代理:为某一个目标操作的结构提供临时的存储空间,以便多个客户端可以共享这些结果。
6)防火墙代理:保护目标不让恶意用户接近。
7)同步化代理:保护目标不让恶意用户接近。
8)智能引用代理:当一个对象被引用时,提供一些额外的操作,如将此对象被调用的次数记录下来等。

1.3 优点

1)代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
2)远程代理使得客户端可以访问在远程机器上的对象。远程机器可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。
3)虚拟代理通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。
4)保护代理可以控制对真实对象的使用权限。

1.4 缺点

1)由于客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
2)实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

二、示例:静态代理模式

2.1 结构图

在这里插入图片描述

2.2 抽象主题角色(抽象权限类)
public interface AbstractPermission {

	public void modifyUserInfo();
	
	public void viewNote();
	
	public void publicshNote();
	
	public void modifyNote();
	
	public void setLevel(int level);
}
2.3 真实主题角色RealPermission(真实权限类)
public class RealPermission implements AbstractPermission{

	@Override
	public void modifyUserInfo() {
		System.err.println("修改用户信息!");
	}

	@Override
	public void viewNote() {
	}

	@Override
	public void publicshNote() {
		System.err.println("发布新帖!");
	}

	@Override
	public void modifyNote() {
		System.err.println("修改发布内容");
	}

	@Override
	public void setLevel(int level) {
		
	}

}
2.4 代理主题角色PermissionProxy (权限代理类)
public class PermissionProxy implements AbstractPermission{
	
	private RealPermission permossion = new RealPermission();
	private int level = 0;

	@Override
	public void modifyUserInfo() {
		if (0 == level) {
			System.out.println("对不起,你没有该权限!");
		} else if (1 == level) {
			permossion.modifyUserInfo();
		}
	}

	@Override
	public void viewNote() {
		System.out.println("查看帖子");
	}

	@Override
	public void publicshNote() {
		if (0 == level) {
			System.out.println("对不起,你没有该权限!");
		} else if (1 == level) {
			permossion.publicshNote();
		}
	}

	@Override
	public void modifyNote() {
		if (0 == level) {
			System.out.println("对不起,你没有该权限!");
		} else if (1 == level) {
			permossion.modifyNote();
		}
	}

	@Override
	public void setLevel(int level) {
		this.level = level;
	}

}

三、示例:动态代理模式

2.1 结构图

在这里插入图片描述

2.2 抽象主题类AbstractSubject
public interface AbstractSubject {
	
	public void request();
	
}
2.3 真实主题类RealSubjectA
public class RealSubjectA implements AbstractSubject{

	@Override
	public void request() {
		System.out.println("真实主题类A!");
	}

}
2.3 真实主题类RealSubjectB
public class RealSubjectB implements AbstractSubject{
	         
	@Override
	public void request() {
		System.out.println("真实主题B!");
	}
	
}
2.4 动态代理类DynamicProxy
public class DynamicProxy implements InvocationHandler{
	
	private Object obj;
	
	public DynamicProxy(Object obj) {
		this.obj = obj;
	}
	
	/**
	 * 
	 * @param proxy 表示代理类
	 * @param method 表示需要代理的方法
	 * @param args 表示代理方法的参数数组
	 * @return
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		preRequest();
		method.invoke(obj, args);
		postRequest();
		return "动态代理执行成功";
	}
	
	public void preRequest() {
		System.out.println("调用之前!");
	}
	public void postRequest() {
		System.out.println("调用之后!");
	}
}
2.5 获取真实类工厂类
public class ProxyFactory {
    public static Object getDynProxy(Object target) {
        InvocationHandler handler = new DynamicProxy(target);
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
    }
}
2.6 客户端使用
public static void main(String[] args) {
     AbstractSubject proxy= (AbstractSubject) ProxyFactory.getDynProxy(new RealSubjectB());
     proxy.request();
 }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书香水墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值