第十八章、代理模式

代理模式也称托付模式,是结构型设计模式之中的一个。是应用广泛的模式之中的一个。

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源代码设计模式解析与实战》读书笔记(十八)的更多相关文章

  1. 《Android源代码设计模式解析与实战》读书笔记(十七)

    第十七章.中介者模式 中介者模式也称为调解者模式或调停者模式,是一种行为型模式. 1.定义 中介者模式包装了一系列对象相互作用的方式.使得这些对象不必相互明显作用.从而使它们能够松散耦合.当某些对象之 ...

  2. 《Android源代码设计模式解析与实战》读书笔记(十四)

    第十四章.迭代器模式 迭代器模式,又叫做游标模式.是行为型设计模式之中的一个.我们知道对容器对象的訪问必定会涉及遍历算法.我们能够将遍历的方法封装在容器中,或者不提供遍历方法,让使用容器的人自己去实现 ...

  3. 《Android源代码设计模式解析与实战》读书笔记(十)

    第十章.解释器模式 解释器模式是一种用的比較少的行为型模式.其提供了一种解释语言的语法或表达式的方式. 可是它的使用场景确实非常广泛,仅仅是由于我们自己非常少回去构造一个语言的文法,所以使用较少. 1 ...

  4. 《Android源代码设计模式解析与实战》读书笔记(二十)

    第二十章.适配器模式 适配器模式是结构型设计模式之中的一个,它在我们的开发中使用率极高,比方ListView.GridView以及RecyclerView都须要使用Adapter. 1.定义 适配器模 ...

  5. 《Android源代码设计模式解析与实战》读书笔记

    1.定义 将对象组合成树形结构以表示"部分-总体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 2.使用场景 (1)表示对象的部分-总体层次结构时. (2)从一个总体 ...

  6. 《Android源代码设计模式解析与实战》读书笔记(八)

    第八章.状态模式 1.定义 状态模式中的行为是由状态来决定,不同的状态下有不同的行为.当一个对象的内在状态改变时同意改变其行为,这个对象看起来像是改变了其类. 2.使用场景 1.一个对象的行为取决于它 ...

  7. 《Android源代码设计模式解析》读书笔记——Android中你应该知道的设计模式

    断断续续的,<Android源代码设计模式解析>也看了一遍.书中提到了非常多的设计模式.可是有部分在开发中见到的几率非常小,所以掌握不了也没有太大影响. 我认为这本书的最大价值有两点,一个 ...

  8. iPhone与iPad开发实战读书笔记

    iPhone开发一些读书笔记 手机应用分类1.教育工具2.生活工具3.社交应用4.定位工具5.游戏6.报纸和杂志的阅读器7.移动办公应用8.财经工具9.手机购物应用10.风景区相关应用11.旅游相关的 ...

  9. 机器学习实战 - 读书笔记(13) - 利用PCA来简化数据

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第13章 - 利用PCA来简化数据. 这里介绍,机器学习中的降维技术,可简化样品数据. ...

随机推荐

  1. 【BZOJ2944】[Poi2000]代码(卡特兰数)

    这题在网上找不到题解,硬写一下午终于写出来了-- 题目: BZOJ2944 分析: 首先明确: 比较两棵节点数相同的二叉树时,根节点是第一关键字,左子树是第二关键字,右子树是第三关键字: 然后我们分析 ...

  2. scrapy 框架持久化存储

    1.基于终端的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表或字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作. # 执行输出指定格式进行存储:将 ...

  3. Android 使用 Application 简单介绍

    Application 配置全局Context 第一步.写一个全局的单例模式的MyApplication继承自Application 覆盖onCreate ,在这个方法里面实例化Application ...

  4. Parameter index out of range (1 > number of parameters, which is 0).

    数据库错误:Parameter   index   out   of   range   (1   >   number   of   parameters,   which   is   0) ...

  5. linux命令(001) -- chkconfig

    一.准备知识 在说明chkconfig命令的用途之前,有必要先了解一下Linux系统中/etc/rc[0-6].d目录的用途. 众所周知,在Linux系统定义了7种不同的启动级别,这7种启动级别的含义 ...

  6. java 任意时间转换日期类型

    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); try { Date dd=sdf.parse("201 ...

  7. B树、B+树、红黑树、AVL树比较

    B树是为了提高磁盘或外部存储设备查找效率而产生的一种多路平衡查找树. B+树为B树的变形结构,用于大多数数据库或文件系统的存储而设计. B树相对于红黑树的区别 在大规模数据存储的时候,红黑树往往出现由 ...

  8. (转)50道JavaScript基础面试题(附答案)

    https://segmentfault.com/a/1190000015288700 1 介绍JavaScript的基本数据类型 Number.String .Boolean .Null.Undef ...

  9. CloseableHttpClient 在使用过程中遇到的问题

    代码是前辈写的,在对代码进行压测的时候遇到了个问题,最大线程是 不能超过setDefaultMaxPerRoute设置的数字,一点超过 就会死掉.这里会报错 connection pool shut ...

  10. CAD调用导角命令,并返回导角的圆弧对象

    主要用到函数说明: _DMxDrawX::SendStringToExecuteFun 把命令当着函数执行,可以传参数,详细说明如下: 参数 说明 IDispatch* pParam 命令参数,IMx ...