第十八章、代理模式

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

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. vb.net实现textbox控件输入指定位数小数方法实现。

    Private Sub textbox1_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPres ...

  2. c# winform控件dock属性停造位置、摆放顺序详解

    dock : [英文释义- 码头.依靠][winform释义- 获取或设置当前控件依靠到父容器的哪一个边缘.] 用途:多数控件都有这个属性,主要用来设置控件的布局. 但对于不太了解这个属性的朋友来说有 ...

  3. CSS——◇demo

    核心思想:嵌套盒子中的◇超过父盒子的部分隐藏. 第一种写法: <!DOCTYPE html> <html> <head> <meta charset=&quo ...

  4. dos2unix xxx.sh

    前几天写了一个Linux的自动化脚本,没有使用变量,就是一些Linux命令的集合 今天试着把一些相同的字段提出来用变量表示,然后在Linux里运行,就发现一直在报错: : command not fo ...

  5. MSSQL高并发下生成连续不重复的订单号

    一.确定需求 只要做过开发的基本上都有做过订单,只要做过订单的基本上都要涉及生成订单号,可能项目订单号生成规则都不一样,但是大多数规则都是连续增长. 所以假如给你一个这样的需求,在高并发下,以天为单位 ...

  6. (转)Java任务调度框架Quartz入门教程指南(二) 使用job、trigger、schedule调用定时任务

    http://blog.csdn.net/zixiao217/article/details/53044890 读完第一节,我们已经对Quartz有了一个大体的认识,它可以定时帮我们执行一些处理程序, ...

  7. struts2.5.2 通配符问题_亲测有用

    学了一段时间struts2,跟着教程做,但发现struts2的版本不同,很多东西的使用是有差异的.例如之前遇到的创建sessionFactory的方式就跟之前版本有着明显的差异.今天又遇到一个问题,那 ...

  8. day2笔记

    今日内容: 1.常用数据类型即数据方法 2.文件处理 3.函数 一 列表: 在[]内,可以存放多个任意类型的值,并以逗号隔开. 一般用于存放学生的爱好,课堂的周期等等 优先掌握的操作: 1.按索引取值 ...

  9. tbType和TypeList操作

    tbType查询数据库后 获得一个DataTable的数据表 数据表是写在内存里面的 可以在这个项目的其他地方去访问它,由于在内存里面 所以访问速度很快 用代码获取它的哪一行的数据供使用 例如 tbB ...

  10. Weex框架源码分析(Android)(一)

    一.weexSDK初始化流程 WXSDKEngine.initialize(Application application,InitConfig config); //WXSDKEngine的init ...