大话设计模式——5.代理模式(Proxy Pattern)

1.定义

为其他具体对象提供一种代理用以控制对这个对象的访问,属于结构型模式。
UML图:
在这里插入图片描述

2.示例

生活中有许多的代理,如房产中介,房主出售的房子挂在中介处,中介帮忙寻找需要的客户,客户不需要直接接触房主。

1)Subject:房子

public interface House {/*** 卖房子*/void sell();
}

2)RealSubject:将要出售的别墅

public class Villa implements House {@Overridepublic void sell() {System.out.println("房东出售大别墅");}
}

3)Proxy:房产中介(静态代理)

public class HouseProxy implements House {private Villa villa = new Villa();@Overridepublic void sell() {findCustomers();villa.sell();}private void findCustomers() {System.out.println("寻找客户");}
}

4)client:客户端运行

public class Main {public static void main(String[] args) {// 无代理House villa = new Villa();villa.sell();System.out.println("----代理----");// 有代理House villaProxy = new HouseProxy();villaProxy.sell();}
}

在这里插入图片描述

2.1 采用动态代理

1)JDK动态代理

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class JDKHouseProxy implements InvocationHandler {// 代理的目标类,运行时进行具体指定private Object targetObj;public Object newInstance(Object targetObj) {// 指定具体的目标类this.targetObj = targetObj;// 构建目标代理类return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(), targetObj.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("实现jdk动态代理 before");// 调用目标类方法Object result = method.invoke(targetObj, args);System.out.println("实现jdk动态代理 after");return result;}
}

2)CGLib动态代理

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;public class CGLibHouseProxy implements MethodInterceptor {public Object newInstance(Object targetObj) {// 创建代理Enhancer enhancer = new Enhancer();// 设置目标类为父类enhancer.setSuperclass(targetObj.getClass());// 设置代理类(回调)enhancer.setCallback(this);return enhancer.create();}@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("CGLib代理 before ");Object result = methodProxy.invokeSuper(o, objects);System.out.println("CGLib代理 after ");return result;}
}

3)运行结果

public class Main {public static void main(String[] args) {// 无代理House villa = new Villa();villa.sell();System.out.println("----代理----");// 有代理House villaProxy = new HouseProxy();villaProxy.sell();// jdk动态代理System.out.println("----JDK代理----");House jdkHouseProxy = (House) new JDKHouseProxy().newInstance(villa);jdkHouseProxy.sell();// CGLib代理System.out.println("----CGLib代理----");House cglibHouseProxy = (House)new CGLibHouseProxy().newInstance(villa);cglibHouseProxy.sell();}
}

在这里插入图片描述

静态代理:由程序或者特定工具生成源代码,在程序编译时已经确定目标类和代理类的关系。容易造成代码冗余,即每个目标类都需要为止创建一个代理类
动态代理:通过java的反射机制在程序运行期间动态的为目标类创建代理类。无需为每个目标类都创建一个代理类,使用更加灵活,具备很好的扩展性

  • JDK代理:目标类需要实现一个接口,为spring默认的代理方式。
  • CGLib代理:有时候目标类是没有实现接口的,那么就采用改方式进行代理。通过在内存中构建目标类的派生类,继承目标类的方法进行改写。采用继承的方式进行代理,因此如果目标类是final类,或者方法是private、static属性
3.总结
  • 无需修改代理的对象源码,符合开闭原则,可使系统具有较好的灵活性和可扩展性
  • 可以对代理的具体对象做增强处理,如增加一些功能等
  • 增加了系统的复杂性与调用过程的链路
4.代理模式 VS 装饰模式
  • 代理模式代理的是具体的对象,可保护目标对象与增强目标对象的功能
  • 装饰模式装饰的是一类对象,可对一类具有共同特点的对象进行控制和处理
  • 装饰模式适合于需要动态地给对象添加新功能的情况,代理模式适合于需要控制对对象访问的情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/536167.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于LSTM实现春联上联对下联

按照阿光的项目做出了学习笔记,pytorch深度学习实战项目100例 基于LSTM实现春联上联对下联 基于LSTM(长短期记忆网络)实现春联上联对下联是一种有趣且具有挑战性的任务,它涉及到自然语言处理(NLP)中的序列…

【node】模块化与包(二)

1、模块化的基本概念 模块化是指解决一个复杂的问题时,自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说,模块是可组合、分解和更换的单元。 (1)模块化的优点 遵循固定规则,把大文件拆分成对立并相互依赖…

数据仓库数据分层详解

数据仓库中的数据分层是一种重要的数据组织方式,其目的是为了在管理数据时能够对数据有一个更加清晰的掌控。以下是数据仓库中的数据分层详解: 原始数据层(Raw Data Layer):这是数仓中最底层的层级,用于存…

算法提高之楼兰图腾(树状数组)

楼兰图腾(树状数组) 核心算法:树状数组 将下标转化为二进制 例如11100100 父节点下标x 子节点下标i 由下图可知 每一个数都可以由其子节点**(如果有)**求和得到**由父节点找子节点:**每个子节点下标 –> x – 1 – lowbit(x – 1)由子节点找父节点&am…

python可视化绘图2.0

五星红旗 import turtle import mathturtle.pensize(3) turtle.colormode(255)# 画背景 turtle.pencolor("#ed120c") turtle.fillcolor("#ed120c") turtle.begin_fill() turtle.penup() turtle.goto(-150, 100) turtle.pendown()for i in [300, 200, 300,…

C语言分析基础排序算法——计数排序

目录 计数排序 计数排序基本思路 计数排序改进思路 计数排序 计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。具体思路为: 统计相同元素出现次数根据统计的结果将序列回收到原来的序列中 计数排序基本思路 基本思路分析: //以…

超分辨率(2)--基于EDSR网络实现图像超分辨率重建

目录 一.项目介绍 二.项目流程详解 2.1.构建网络模型 2.2.数据集处理 2.3.训练模块 2.4.测试模块 三.测试网络 一.项目介绍 EDSR全称Enhanced Deep Residual Networks,是SRResnet的升级版,其对网络结构进行了优化(去除了BN层),省下来…

解决ipconfig不是内部或外部命令,也不是可运行的程序或批处理文件

问题所示:ipconfig不是内部或外部命令,也不是可运行的程序或批处理文件。 解决办法如下: 1.右击此电脑,点击属性设置: 2.点击高级系统设置 3.点击进入环境变量 4.在系统变量中进行设置,双击PATH进行配置 5.点击新建&am…

python-0007-django模版

介绍 模版是对js,html等资源的封装 新建 在项目路径下新建模版文件夹templates(可以为其他名称),要是想细分业务的话,还可以在templates路径下继续建文件夹。如下图: 注册模版 在项目的settings找到T…

基于springboot实现线上阅读系统项目【项目源码+论文说明】

基于springboot实现线上阅读系统演示 摘要 随着社会发展速度的愈来愈快,以及社会压力变化的越来越快速,致使很多人采取各种不同的方法进行解压。大多数人的稀释压力的方法,是捧一本书籍,心情地让自己沉浸在情节里面,以…

DARTS: DIFFERENTIABLE ARCHITECTURE SEARCH

DARTS:可微架构搜索 论文链接:https://arxiv.org/abs/1806.09055 项目链接:https://github.com/quark0/darts ABSTRACT 本文通过以可微分的方式表述任务,解决了架构搜索的可扩展性挑战。与在离散和不可微搜索空间上应用进化或强…

如何在WordPress网站上设置多语言展示

在今天的全球化世界中,拥有多语言网站对于吸引更广泛的受众至关重要。前不就我们遇到Hostease的客户咨询我们的在线客服,他想要对他的wordpress网站支持多语言。我们提供给客户可以尝试以下的插件来支持多语言。 在本教程中,我们将逐步介绍如…