代理模式(Proxy Pattern)

代理模式(Proxy Pattern)

概述

代理是一种结构型设计模式,让你能够提供对象的替代品或其占位符。代理控制着对于原对象的访问,并允许在将请求提交给对象前后进行一些处理。

分类

  • 远程代理(Remote Proxy):控制对远程对象(不同地址空间)的访问,它负责将请求及其参数进行编码,并向不同地址空间中的对象发送已经编码的请求。
  • 虚拟代理(Virtual Proxy):根据需要创建开销很大的对象,它可以缓存实体的附加信息,以便延迟对它的访问,例如在网站加载一个很大图片时,不能马上完成,可以用虚拟代理缓存图片的大小信息,然后生成一张临时图片代替原始图片。
  • 保护代理(Protection Proxy):按权限控制对象的访问,它负责检查调用者是否具有实现一个请求所必须的访问权限。
  • 智能代理(Smart Reference):取代了简单的指针,它在访问对象时执行一些附加操作:记录对象的引用次数;当第一次引用一个对象时,将它装入内存;在访问一个实际对象前,检查是否已经锁定了它,以确保其它对象不能改变它。

应用实例

  1. Windows 里面的快捷方式
  2. 猪八戒去找高翠兰结果是孙悟空变的,可以这样理解:把高翠兰的外貌抽象出来,高翠兰本人和孙悟空都实现了这个接口,猪八戒访问高翠兰的时候看不出来这个是孙悟空,所以说孙悟空是高翠兰代理类
  3. 买火车票不一定在火车站买,也可以去代售点
  4. 代购
  5. 一张支票或银行存单是账户中资金的代理。支票在市场交易中用来代替现金,并提供对签发人账号上资金的控制
  6. 信用卡是银行账户的代理,银行账户则是一大捆现金的代理。它们都实现了同样的接口,均可用于进行支付。消费者会非常满意,因为不必随身携带大量现金;商店老板同样会十分高兴,因为交易收入能以电子化的方式进入商店的银行账户中,无需担心存款时出现现金丢失或被抢劫的情况
  7. Spring AOP

优点

  • 职责清晰

    真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件事务,附带的结果就是编程简洁清晰。

  • 高扩展性

    具体主题角色是随时都会发生变化的,只要它实现了接口,甭管它如何变化,都逃不脱如来佛的手掌(接口),那我们的代理类完全就可以在不做任何修改的情况下使用。

  • 智能化

基本结构

  1. 服务接口(Service Interface)声明了服务接口。代理必须遵循该接口才能伪装成服务对象。
  2. 服务(Service)类提供了一些实用的业务逻辑。
  3. 代理(Proxy)类包含一个指向服务对象的引用成员变量。代理完成其任务(例如延迟初始化、记录日志、访问控制和缓存等)后会将请求传递给服务对象。通常情况下,代理会对其服务对象的整个生命周期进行管理。
  4. 客户端(Client) 能通过同一接口与服务或代理进行交互,所以你可在一切需要服务对象的代码中使用代理。

静态代理【重点】

概述

静态代理是指预先确定了代理与被代理者的关系,即代理类与被代理类的依赖关系在编译期间就确定了。

静态代理又分为强制代理和普通代理。普通代理的要求就是客户端只能访问代理角色,而不能访问真实角色;强制代理的概念就是要从真实角色查找到代理角色,不允许直接访问真实角色。

案例一

描述

永强的公司老板突然在发工资的前一天带着小姨子跑路了,可怜的永强一身房贷,被迫提起劳动仲裁,劳动局就会为其指派一位代理律师全权负责永强的仲裁事宜。那这里面就是使用了代理模式,因为在劳动仲裁这个活动中,代理律师会全权代理永强。

案例代码

Interface

// 诉讼接口
public interface LawSuit {
    // 提起诉讼
    void submit();

    // 法庭辩护
    void defend();
}

Service

// 诉讼当事人(原告)
public class Parties implements LawSuit {
    @Override
    public void submit() {
        System.out.println("老板欠薪跑路,证据确凿!!!");
    }

    @Override
    public void defend() {
        System.out.println("铁证如山,欠债还钱");
    }
}

Proxy

// 代理律师类,全权负责案件的代理
public class Lawyer implements LawSuit {
    // 包含一个被代理的对象
    private final LawSuit lawSuit;

    // 通过构造方法传递被代理对象
    public Lawyer(LawSuit lawSuit) {
        this.lawSuit = lawSuit;
    }

    @Override
    public void submit() {
        // 搜集证据
        this.gatherEvidence();

        // 提起诉讼
        this.lawSuit.submit();
    }

    @Override
    public void defend() {
        // 法庭辩护
        this.lawSuit.defend();

        // 交换意见
        this.compareNotes();
    }

    // 搜集证据(属于增强的方法)
    private void gatherEvidence() {
        System.out.println("搜集证据");
    }

    // 交换意见(属于增强的方法)
    private void compareNotes() {
        System.out.println("与审判长、审判员交换意见,被告如果不服,代其上诉或申诉");
    }
}

Client

// 开庭
public class Court {
    @Test
    public void testLawSuit() {
        // 当事人安排上
        Parties parties = new Parties();

        // 当事人的代理律师安排上
        Lawyer lawyer = new Lawyer(parties);

        // 代理律师进行提起诉讼以及法庭辩护
        lawyer.submit();
        lawyer.defend();
    }
}

案例二

描述

玉田是个游戏死忠粉,每天最大的乐趣就是在游戏里大杀四方,但是游戏打时间长了,腰酸背痛、眼睛干涩、手臂酸麻,等等,也就是网络成瘾综合症都出来了。玉田想玩游戏,但又不想碰触到游戏中的烦恼,如何解决呢?有办法,现在游戏代练的公司非常多,于是玉田把自己的账号交给代练人员,由他们去帮着升级,去打怪,非常好的想法。游戏代练者,它也不能有作弊的方法(开挂),也只能手动打怪,这个时候,玉田的代练者就上着他的号,扮演着他的角色在游戏里继续大杀四方。

案例代码

Interface

// 游戏接口
public interface GamePlay {
    // 登录
    void login();

    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值