定义
为其他对象提供一种代理以控制对这个对象的访问
使用场景
当无法或不想直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口
UML 类图
- Subject: 抽象主题类。声明真实主题与代理的共同接口方法,该类既可以是一个抽象类也可以是一个接口
- RealSubject: 真实主题类/被委托类/被代理类。该类定义了代理所表示的真实对象,由其执行具体的业务逻辑方法,而客户类则通过代理类间接地调用真实主题类中定义的方法
- ProxySubject: 代理类。该类持有一个对真实主题类的引用,在其所实现的接口方法中调用真实主题类中相应的接口方法执行,以此起到代理的作用
- Client: 客户类。即使用代理类的类型
代理类型
代理模式分为:静态代理与动态代理
- 静态代理
在我们的代码运行前代理类class 编译文件就已存在,代理类和委托类的关系在运行前就确定了
- 动态代理
通过反射机制动态地生成代理者的对象。(在code 阶段不需要代理谁,代理谁我们将在执行阶段决定。Java 提供了动态代理接口InvocationHandler,实现该接口需要重写其调用方法)
实例
- 共有代码
interface ILawsuit {
fun submit() // 提交申请
fun burden()// 进行举证
fun defend()// 开始辩论
fun finish()// 诉讼完成
}
class Min : ILawsuit {
override fun submit() {
System.out.println("Min-------> 提交申请")
}
override fun burden() {
System.out.println("Min-------> 进行举证")
}
override fun defend() {
System.out.println("Min-------> 开始辩论")
}
override fun finish() {
System.out.println("Min-------> 诉讼完成")
}
}
- 静态代理
class Lawyer(val mILawsuit: ILawsuit) : ILawsuit {
override fun burden() {
mILawsuit.burden()
}
override fun defend() {
mILawsuit.defend()
}
override fun finish() {
mILawsuit.finish()
}
override fun submit() {
mILawsuit.submit()
}
}
fun main(args: Array<String>) {
val min = Min()
// 静态代理
val lawyer = Lawyer(min)
lawyer.submit()
lawyer.burden()
lawyer.defend()
lawyer.finish()
}
- 动态代理
class DynamicProxyLawyer(private val obj: Any) : InvocationHandler {
@Throws(Throwable::class)
override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any? {
return method!!.invoke(obj, *(args ?: emptyArray()))
}
}
fun main(args: Array<String>) {
val min = Min()
// 动态代理
val proxy = DynamicProxyLawyer(min)
val lawyer = Proxy.newProxyInstance(min::class.java.classLoader, arrayOf(ILawsuit::class.java), proxy) as ILawsuit
lawyer.submit()
lawyer.burden()
lawyer.defend()
lawyer.finish()
}
补充:从适用范围区分不同类型的代理
- 远程代理
- 虚拟代理
- 保护代理
- 智能代理
Android 源码中的代理模式实现
ActivityManagerNative 和ActivityManagerProxy 都实现了IActivityManager , ActivityManagerProxy 是代理部分,而ActivityManagerNative 就是真实部分,但ActivityManagerNative是个抽象类,大部分具体逻辑实现都由其子类ActivityManagerService承担