android 设计模式之代理模式(Proxy Pattern)

代理模式(Proxy Pattern)

文章目录

  • 代理模式(Proxy Pattern)
    • 静态代理:
    • 动态代理

前几天听同事说了有个代理模式,但是以前我基本不怎么了解,然后就抽时间去看了看,下面是我看后总结

代理模式就是使用代理对象来操作目标对象,并在代理对象中进行扩展(开闭原则:对扩展开放,对修改关闭)的一种设计模式,

例子:

上大学时,学校内的网络是一个局域网,想上网就得花钱开通账号,虽然不多,但是更想免费用啊,后来在百度上查到这么一个东西;然后在学校找了个服务器,我把自己电脑通过连接到服务器上,就这样我就可以免费上网了…

再比如说一个我们经常听到的,黄牛党,我们买票买不到时,让他们替代给我们买,我们也可以把它称为代理模式

图示:

android 设计模式之代理模式(Proxy Pattern)_第1张图片

实现:

静态代理:

静态代理在使用需要定义接口或者父类,被代理类和代理类同时实现该接口或者继承该父类;
特点:
在每次新增函数时,需要要在接口中添加一个新方法,然后在目标对象中实现这个方法,并且在代理对象中实现相应的代理方法,所以我们可以通过反射来实现动态代理

public interface Internet {
	boolean internet();
}

目标类:

public class MyComputer implements Internet {

	@Override
	public boolean internet() {
		// TODO 连接网络
		System.out.println("电脑连接网络成功");
		return false;
	}
}

代理类:

public class ServiceProxy implements Internet {

	private Internet mInternet;

	public ServiceProxy(Internet mInternet) {
		this.mInternet = mInternet;
	}

	@Override
	public boolean internet() {
		// TODO 服务器连接网络,服务器与客户端建立连接,这样客户端就可以通过代理来访问网络了
		// 在代理对象中执行目标对象的方法,告诉目标对象他想做的事情,我已经给他做好了
		mInternet.internet();
		return false;
	}
}

测试类:

public class ProxyTest {

	public static void main(String[] args) {
		// 目标对象
		MyComputer computer = new MyComputer();
		// 代理对象,将目标对象传给代理对象,建立代理关系
		ServiceProxy serviceProxy = new ServiceProxy(computer);
		// 执行代理函数
		serviceProxy.internet();
	}
}

动态代理

通过Api中的Proxy,InvocationHandler类实现动态代理,它们的原理就是反射
在反射中我们可以通过对象或Class,通过Class对象获取到它中的所有函数,然后根据Method就可以调用相对于的函数了,如果有兴趣可以自己去看看它们的源码

需要实现的接口:

public interface Internet {
	boolean internet();
}

目标对象实现接口

public class MyComputer implements Internet {

	@Override
	public boolean internet() {
		// TODO 连接网络
		System.out.println("电脑连接网络成功");
		return false;
	}
}

测试类:通过Proxy和InvocationHandler实现动态代理;

public class ProxyTest {

	public static void main(String[] args) {
		Internet mInternet = new MyComputer();
		Internet aInternet = (Internet) Proxy.newProxyInstance(mInternet.getClass().getClassLoader(),
				mInternet.getClass().getInterfaces(), new InvocationHandler() {
					// 回调方法 拦截到目标对象的时候执行
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						if (proxy instanceof Internet) {
							System.out.println("true");
						} else {
							System.out.println("false");
						}

						// 通过method.invoke(Object object,Object[] args)调用object中的对应的函数,args是参数
						return method.invoke(mInternet, args);
					}
				});
		aInternet.internet();

	}
}

当然了,我们还可以定义一个代理类实现InvocationHandler,在该类中实现事件回调处理.代码就不写了
使用动态代理可以更好的对代理者和被代理者进行解耦.

引用android源码设计模式解析与实战中一段话:
代理从适用范围来区分可以分为:

  1. 远程代理(remote proxy):为某个对象跨进程提供局部代理
  2. 虚拟代理(virtual proxy):使用一个代理对象表示一个十分耗资源的对象并在真正需要时才创建.
  3. 保护代理(protection proxy):使用代理控制对原始对象的访问.该类型的代理常被用于原始对象有不同访问权限的情况.
  4. 智能引用(smart reference):在访问原始对象时执行一些自己的附加操作并对指向原始对象的引用计数.

你可能感兴趣的:(android,设计模式,代理模式)