第十八章、代理模式

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

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. HTML--文本输入框、密码输入框

    当用户要在表单中键入字母.数字等内容时,就会用到文本输入框.文本框也可以转化为密码输入框. 语法: <form> <input type="text/password&qu ...

  2. day03_12/13/2016_bean的管理之作用域与初始化时间

    在Spring中,Bean有几种作用域: 1.singleton作用域 当一个bean的作用域设置为singleton,那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean ...

  3. python 分割文件、组合文件

    import glob big_file = open('index.sql', 'rb') bak_file = 'index_bak' i = 1 while True: chunk = big_ ...

  4. 4.用Redis Desktop Manager连接Redis(Windows)

    相比连接CentOS的Redis,在Windows中的操作简单得让人感动. 所以这里我们使用的服务器系统是Windows Server 2016 R2. 而Windows版本的Redis官方网站并没有 ...

  5. C# 统计字符串出现的个数

    string str1 = "123AAA456AAAA789AAAAAAA1011"; string str2 = "123456789AAA23456789AAAA3 ...

  6. CentOS下修改root用户名

    修改root登录用户名减少Linux云主机“被暴力破解”警告,登录云主机的时候就先显示登录失败多少次.其是公网有人在扫用弱密码破解登录. 所谓暴力破解,就是用“用户名“+”密码”穷举的方式进行远程登录 ...

  7. 11.11如何卖到一个亿:从0到1的电商爆品打造术 电子书 PDF

    内容转自:https://download.csdn.net/download/chenyao1994/11191034 下载地址:https://pan.baidu.com/s/1uQ1cjm9QH ...

  8. uva 202(Repeating Decimals UVA - 202)

    题目大意 计算循环小数的位数,并且按照格式输出 怎么做 一句话攻略算法核心在于a=a%b*10,用第一个数组记录被除数然后用第二个数组来记录a/b的位数.然后用第三个数组记录每一个被除数出现的位置好去 ...

  9. ListView学习(一)

    最近了解了LIstView的用法,在听了孙老师的课程后,终于对Adapter有了一定的理解,特作此文记之. ListView在App当中应用相当广泛,比如QQ好友列表.微博等等,都是某种特定的列表,所 ...

  10. PAT 1115 Counting Nodes in a BST

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...