设计模式--代理模式(Proxy Pattern)-静态代理


间接的“美”
  中国人是一个含蓄的民族,讲究微妙和间接的交流方式。对象间的间接通信也同样是面向对象设计中一条重要的审美观。间接性的通信可以给出较低的耦合关系,较强的合作关系,以及微妙的结构和易于复用的设计架构。
                           ----<<Java与模式>>


1.引言


定义
  代理模式的英文叫Proxy或Surrogate。所谓代理就是指一个人或者一个机构代表另一个人或另一个机构采取行动。在一些情况下,一个客户不想或者不能直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介作用。
意图
  为其他对象提供一种代理以控制对这个对象的访问。


2.代理模式的分类

按职责来划分,通常有以下使用场景:
1、远程代理 :为一个位于不同地址空间的对象提供一个局域代表对象。这个不同的地址空间可以在本机上,也可以在另一台机器中,远程代理又叫“大使”(Ambassaor)。
2、虚拟代理 :根据需要创建一个资源消耗较大的对象,使得此对象只在需要时被创建。
3、Copy-on-Write 代理 :虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时才启动。
4、保护(Protect or Access)代理 :控制对一个对象的访问,如果有需要,可以给不同用户提供不同的使用权限。
5、Cache代理:为某一个目标的操作结果提供临时的储存空间,以便多个客户端可以共享这个结果。
6、防火墙(Firewall)代理:保护目标,不让恶意用户接近。
7、同步化(Synchronization)代理 :使几个用户在同时使用一个对象而没有冲突。
8、智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如记录此对象被调用的次数。


3.代理模式的结构

代理模式涉及的角色有:

  • 抽象主题角色:声明了真实主题和代理主题的共同接口。这样一来任何使用真实主题的地方都可以使用代理主题。
  • 代理主题(Proxy)角色:代理主题角色内部含有一个对真实主题角色的引用。从而可以在任何时候操作真实主体对象;代理主题角色提供一个与真实主题角色相同的接口,以便在任何时候都可以代替真实主题;控制对真实主题的引用,负责在需要的时候创建真实主题对象(或删除真实主题对象);代理主题通常在客户端调用真实主题之前或之后都要执行某个操作,而不是单纯将调用传给真实主题。
  • 真实主题角色:定义了代理角色所代表的的真实对象。
    实现的类图如下图所示:
    51.png

4.代理模式的时序

静态的类图不适合反映模式在运行时的特性,时序图则更为形象,下图是代理模式的时序图表示:
52.png

5.静态代理

(1) 静态代理
  由程序员创建或特定工具自动生成源代码,也就是在编译时就已经将接口,被代理类,代理类等确定下来。在程序运行之前,代理类的.class文件就已经生成。

(2) 静态代理简单实现
  根据上面代理模式的类图,来写一个简单的静态代理的例子。我这儿举一个比较粗糙的例子,假如一个班的同学要向老师交班费,但是都是通过班长把自己的钱转交给老师。这里,班长就是代理学生上交班费,
班长就是学生的代理。
  首先,我们创建一个Person接口。这个接口就是学生(被代理类),和班长(代理类)的公共接口,他们都有上交班费的行为。这样,学生上交班费就可以让班长来代理执行。
代码清单一:抽象主题角色的源代码

// 创建一个代理类和真实类的共同接口Person
public interface Person{
    // 上交班费
    void giveMoney();
}

代码清单二:真实主题源代码
Student类实现Person接口。Student可以具体实施上交班费的动作。

public class Student implements Person {
    public Student() {
    }
    @Override
    public void giveMoney() {
       System.out.println("上交班费");
    }
}

代码清单三:代理主题源代码

/**
 * 学生代理类,也实现了Person接口,保存一个学生实体,这样既可以代理学生产生行为
 */
public class StudentsProxy implements Person{
    //被代理的学生
    Student stu;
    public StudentsProxy() {
    } 
    //代理上交班费,调用被代理学生的上交班费行为
    public void giveMoney() {
        // 调用之前进行操作
        preGive();
        if(stu == null){
            stu = new Student();
        }
        stu.giveMoney();
        // 调用之后进行操作
        postGive();
    }
    public void preGive(){
         System.out.println("Before:在give Money之前进行一些操作");
    }
    public void postGive(){
        System.out.println("After:在give Money之后进行一些操作");
    }
}

代码清单四:测试源代码

/**
 * Created by yucheng on 2018/8/9.
 */
public class StudentProxyDemo {
    public static void main(String[] args) {
        Person p = new StudentProxy();
        p.giveMoney();
    }
}

输出结果
Before Give Money!
上交班费!
After Give Money!


说明
  代理模式最主要的就是有一个公共接口Person,一个具体的类Student,一个代理类StudentProxyDemo,代理类持有具体类的实例,代为执行具体类实例方法。
  上面说到,代理模式就是在访问实际对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。这里的间接性就是指不直接调用实际对象的方法,那么我们在代理过程中就可以加上一些其他用途。就如这个例子里的preGive()和postGive()方法。特别是在Spring AOP编程中。在切点(即一个个方法)的前后我们可以进行一系列操作。


这一章,我们主要讲述的是代理模式的基本概念、思想已经应用之静态代理。而下一章,我将继续代理模式之“动态代理”的讲述。敬请期待!
推荐阅读:
设计模式--代理模式(Proxy Pattern)-动态代理

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容