《Android源代码设计模式解析与实战》读书笔记(十八)
第十八章、代理模式
代理模式也称托付模式,是结构型设计模式之中的一个。是应用广泛的模式之中的一个。
1.定义
为其它对象提供一种代理以控制对这个对象的訪问。
2.使用场景
当无法或不想直接訪问某个对象或訪问某个对象存在困难时能够通过一个代理对象来间接訪问,为了保证client使用的透明性。托付对象与代理对象须要实现相同的接口。
3.UML类图
(1)Subject:抽象主题类。声明真实主题与共同接口方法,该类能够是抽象类或接口。
(2)RealSubject:真实主题类(被托付类)。尤其运行详细的业务逻辑方法。
(3)Proxy:代理类(托付类),该类持有一个对真实主题类的引用。在其所实现的接口方法中调用真实主题类中对应的接口方法运行,以此起到代理作用。
4.简单实现
书中样例:以小民诉讼的流程举例。那么须要代理律师代理,诉讼简单流程:提交申请–>进行举证–>開始辩护–>诉讼完毕。
诉讼接口类:
public interface ILawsuit {
/**
* 提交申请
*/
void submit();
/**
* 进行举证
*/
void burden();
/**
* 開始辩护
*/
void defend();
/**
* 诉讼完毕
*/
void finish();
}
详细诉讼人小民:
public class XiaoMin implements ILawsuit{
@Override
public void submit() {
//小民申请仲裁
System.out.println("老板年底拖欠工资。特此申请仲裁。");
}
@Override
public void burden() {
//小民提交证据
System.out.println("这是合同书和过去一年的银行工资流水!");
}
@Override
public void defend() {
//铁证如山
System.out.println("证据确凿,不须要再说什么!
");
}
@Override
public void finish() {
//结果
System.out.println("诉讼成功。判决老板即日起七天内结算工资!");
}
}
代理律师:
public class Lawyer implements ILawsuit{
private ILawsuit mLawsuit; //持有一个详细被代理者的引用
public Lawyer(ILawsuit lawsuit) {
this.mLawsuit = lawsuit;
}
@Override
public void submit() {
mLawsuit.submit();
}
@Override
public void burden() {
mLawsuit.burden();
}
@Override
public void defend() {
mLawsuit.defend();
}
@Override
public void finish() {
mLawsuit.finish();
}
}
開始仲裁:
public class Client {
public static void main(String[] args) {
//构造出诉讼人小民
ILawsuit xiaomin = new XiaoMin();
//构造一个代理律师,并将小民传递进去
ILawsuit lawyer = new Lawyer(xiaomin);
//律师提交申请
lawyer.submit();
//律师进行举证
lawyer.burden();
//律师代小民辩护
lawyer.defend();
//完毕诉讼
lawyer.finish();
}
}
结果:
老板年底拖欠工资,特此申请仲裁! 这是合同书和过去一年的银行工资流水! 证据确凿,不须要再说什么!
诉讼成功,判决老板即日起七天内结算工资!
相同我们也能够代理其它人,仅仅须要实现ILawsuit就可以。上面的代理模式也叫静态代理,也就是在代码运行前代理类的class文件就已经存在。
那么相反。当然也会有动态代理,以下用动态代理实现上述样例:
Java提供了一个便捷的动态代理接口InvocationHandler。我们来实现它:
public class DynamicPorxy implements InvocationHandler{
private Object obj; //被代理类的引用
public DynamicPorxy(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 调用被代理类对象的方法
Object result = method.invoke(obj, args);
return result;
}
}
这里我们通过invoke方法来调用详细的被代理方法。
改动后的Client类:
public class Client {
public static void main(String[] args) {
//构造出诉讼人小民
ILawsuit xiaomin = new XiaoMin();
//1.静态代理
//构造一个代理律师。并将小民传递进去
//ILawsuit lawyer = new Lawyer(xiaomin);
//--------------------------------------
//2.动态代理
//构造一个动态代理
DynamicPorxy proxy = new DynamicPorxy(xiaomin);
//获取被代理类小民的ClassLoader
ClassLoader loader = xiaomin.getClass().getClassLoader();
//动态构造一个代理者律师
ILawsuit lawyer = (ILawsuit) Proxy.newProxyInstance(loader, new Class[]{ ILawsuit.class }, proxy);
//律师提交申请
lawyer.submit();
//律师进行举证
lawyer.burden();
//律师代小民辩护
lawyer.defend();
//完毕诉讼
lawyer.finish();
}
}
结果不变。由此能够看出动态代理通过一个代理类来处理N多个被代理类,事实上质是对代理者与被代理者解耦。
相对而言静态代理则仅仅能为给定接口下的实现类做代理,假设接口不同那么就须要又一次定义不同的代理类。较为复杂,可是静态代理更符合面向对象原则。详细使用哪种方式,依据个人喜好。
5.Android源代码中的代理模式实现
1.ActivityManagerProxy代理类
ActivityManager是Android中管理和维护Activity的相关信息的类,为了隔离它与ActivityManagerService,有效减少二者的耦合,在这中间使用了ActivityManagerProxy代理类,全部对ActivityManagerService的訪问都转换成对代理类的訪问,这样ActivityManager就与ActivityManagerService解耦了。
6.总结
1.长处
(1)对代理者与被代理者进行解耦。
(2)代理对象在client和目标对象之间起到一个中介的作用,这样能够起到对目标对象的保护。
2.缺点
基本没有缺点,真要说缺点就是设计模式的通病:对类的添加。
相关文章
- [Android Pro] 完美解决 No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
- [Android Pro] android 4.4 Android原生权限管理:AppOps
- Android WiFi Management Sample
- Android 开发之旅:短信的收发及在android模拟器之间实践(二)
- Android API之android.provider.ContactsContract.Contacts
- Android API之android.os.AsyncTask
- Android开发学习---使用Intelij idea 13.1 进行android 开发
- Android绘图机制(二)——自定义View绘制形, 圆形, 三角形, 扇形, 椭圆, 曲线,文字和图片的坐标讲解
- Android--百度地图之基础地图(三)
- macos安装android studio(Android Studio 2021.1.1)
- Android stuido 解决Caused by: android.view.InflateException: Binary XML file line #8: Binary XML file
- Android GIS开发系列-- 入门季(2) MapView与图层介绍
- Android 快速运行开源项目
- Android常用8种设计模式(一)
- Android 设计模式
- Error:Execution failed for task ‘:app:packageRelease‘. > com.android.ide.common.signing.KeytoolExcep
- android 设计模式之命令模式
- Android 10.0 动态修改ro开头系统属性的值
- 关于Android SDK Manager更新速度慢的解决方法
- 【Android Gradle 插件】自定义 Gradle 任务 ① ( Gradle 面板显示任务列表 | 自定义任务生成与显示分组 )
- 【Android Gradle 插件】Android Module 模块 build.gradle 构建脚本 Groovy 语法分析 ① ( Gradle 二进制插件引入 | Gradle依赖配置 )
- 【Android Gradle 插件】TestOptions 配置 ④ ( org.gradle.api.tasks.testing.Test 单元测试配置类 | Android 单元测试示例 )
- 【Android 应用开发】Android 开发环境下载地址 -- 百度网盘 adt-bundle android-studio sdk adt 下载
- 跟着Android学设计模式:代理(proxy)
- BaiduMap_SDK_DEMO_3.0.0_for_Xamarin.Android_by_imknown
- Android 设计模式 之 单例模式
- Android设计模式之单例模式的七种写法
- Android串口控制台改为root(十六)
- Android 开源项目android-open-project解析之(三) ScrollView,TimeView,TipView,FlipView
- Android培训班(109)start_kernel函数6
- Android 系统休眠唤醒 android-suspend
- 【Android-Jetpack进阶】6、WorkManager 后台线程、一次性、周期性、任务链的 Work
- 【Android机器学习实战】2、用 TensorFlowLite 做目标检测
- Android 11.0 原生SystemUI下拉通知栏每条通知默认展开
- android开发,Android Studio在创建安卓虚拟设备(AVD)时,报错:Unknown Error
- Android内核开发:学会分析系统的启动log