博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【设计模式】(十二)代理模式(Proxy Pattern)
阅读量:2039 次
发布时间:2019-04-28

本文共 1928 字,大约阅读时间需要 6 分钟。

在有些情况下,一个客户不能或者不想直接访问另一个对象,这时需要找一个中介帮忙完成某项任务,这个中介就是代理对象。例如,购买火车票不一定要去火车站买,可以通过 12306 网站或者去火车票代售点买。又如找女朋友、找保姆、找工作等都可以通过找中介完成。

在软件设计中,使用代理模式的例子也很多,例如,要访问的远程对象比较大(如视频或大图像等),其下载要花很多时间。还有因为安全原因需要屏蔽客户端直接访问真实对象,如某单位的内部数据库等。

1. 代理模式的介绍

代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式

在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介

根据代理的创建时期,代理模式分为静态代理动态代理

  • 静态:由程序员创建代理类或特定工具自动生成源代码再对其编译,在程序运行前代理类的 .class 文件就已经存在了。
  • 动态:在程序运行时,运用反射机制动态创建而成

2. 代理模式的结构

代理模式的主要角色如下。

  1. 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
  2. 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
  3. 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

在代码中,一般代理会被理解为代码增强,实际上就是在原代码逻辑前后增加一些代码逻辑,而使调用者无感知。 

3. 代理模式的实现

定义抽象主题类:

package com.siyi.proxypattern;//抽象主题public interface Subject {    public void request();}

定义真实主题类:

package com.siyi.proxypattern;//真实主题public class RealSubject implements Subject {    public void request() {        System.out.println("request...");    }}

定义代理类:

package com.siyi.proxypattern;//代理public class Proxy implements Subject {    private Subject subject;    public Proxy(Subject subject){        this.subject = subject;    }    @Override    public void request() {        preRequest();        subject.request();        postRequest();    }    public void preRequest() {        System.out.println("before...");    }    public void postRequest() {        System.out.println("after...");    }}

Main方法:

package com.siyi.proxypattern;public class Main {    public static void main(String[] args) {        Subject subject = new Proxy(new RealSubject());        subject.request();    }}

运行结果:

before...request...after...

4. 代理模式的优缺点

优点:

  • 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
  • 代理对象可以扩展目标对象的功能;
  • 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性

缺点:

  • 代理模式会造成系统设计中类的数量增加
  • 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
  • 增加了系统的复杂度;

为了解决上面的缺点,所以我们一般使用动态代理。

5. 动态代理的常用实现方式

点击查看:

6. JDK动态代理的实现原理

点击查看:

转载地址:http://qryof.baihongyu.com/

你可能感兴趣的文章
@ConditionalOnProperty来控制Configuration是否生效
查看>>
springboot使用加密的配置属性
查看>>
聊聊 Java 中日期的几种常见操作 —— 取值、转换、加减、比较
查看>>
强大易用的日期和时间库 Joda Time
查看>>
vi中跳到文件的第一行和最后一行
查看>>
jasypt-spring-boot修改加解密用得盐的key
查看>>
Maven常见异常及解决方法
查看>>
Java 8简明教程
查看>>
go学习笔记(1 基础)
查看>>
go学习笔记(2指针)
查看>>
go学习笔记(3结构体)
查看>>
Go学习笔记(4语言切片(Slice))
查看>>
go是面向对象语言吗?
查看>>
golang 格式“占位符”%d,%f,%s等应用类型
查看>>
GO语言学习系列九——GO的结构(struct)与方法(method)
查看>>
Go 单例模式
查看>>
由浅入深剖析 go channel
查看>>
golang 中 sync.Mutex 和 sync.RWMutex
查看>>
为什么Java永远比C++慢?
查看>>
大众点评 链路监控cat源码的几个片段分析(初始化 messageId的传递)
查看>>