首页 > 其他分享 >设计模式之代理模式

设计模式之代理模式

时间:2024-05-13 14:31:43浏览次数:20  
标签:target 对象 代理 模式 目标 设计模式 ITeacherDao public

  1. 为什么要代理?

    • 解决在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。
  2. 什么是代理模式?

    • 代理模式(Proxy Pattern)是一种结构性模式。代理模式为一个对象提供了一个替身,以控制对这个对象的访问。即通过代理对象访问目标目标对象,可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。
  3. 代理模式分为静态代理和动态代理

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

    • 静态代理是定义父类或者接口,然后被代理对象(即目标对象)与代理对象一起实现相同的接口或者是继承相同父类。代理对象与目标对象实现相同的接口,然后通过调用相同的方法来调用目标对象的方法。

      • 优点:可不修改目标对象的功能,通过代理对象对目标功能扩展。
      • 缺点:因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,一旦接口增加方法,目标对象与代理对象都要维护。
    • 举例

    • ITeacherDao:接口

    • TeacherDao:目标对象,实现接口ITeacherDao

    • TeacherDAOProxy:代理对象,也实现ITeacherDao接口,并且聚合ITeacherDao属性,通过构造器传参设置值,调用的时候通过调用代理对象的方法来调用目标对象。

  5. 动态代理

    • 动态代理也叫JDK代理、接口代理。它使代理对象不需要实现接口(但目标对象要实现接口),代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象。

    • 即使用JDK包java.lang.reflect.Proxy中的newProxyInstance方法来动态的创建目标对象(被代理对象),该方法需要如下接收三个参数:

      • ClassLoader loader:指定当前目标对象使用的类加载器
      • Class<?>[] interfaces :目标对象实现的接口类型,使用泛型方法确认类型
      • InvocationHandler h :事情处理,执行目标对象的方法时,会触发事情处理器方法,把当前执行的目标对象方法作为参数传入

    • 核心是getProxyInstacne()

      • 根据传入的对象TeacherDao目标对象
      • 利用反射机制,返回一个代理对象
      • 然后通过代理对象,调用目标对象方法
    //接口
    public interface ITeacherDao {
    	void teach();
    	void test(String name);
    }
    //目标对象
    public class TeacherDao implements ITeacherDao {
    	@Override
    	public void teach() {
    		System.out.println("一键三连");
    	}
    	@Override
    	public void test(String name) {
    		System.out.println("传参测试:" + name);
    	}
    }
    //代理对象
    public class ProxyFactory {
    	//维护一个目标对象 , Object
    	private Object target;
    	//构造器 , 对target 进行初始化
    	public ProxyFactory(Object target) {
    		this.target = target;
    	}
    	//动态生成一个代理对象
    	public Object getProxyInstance() {
    		return Proxy.newProxyInstance(target.getClass().getClassLoader(),
    				target.getClass().getInterfaces(),
    				new InvocationHandler() { //匿名类重写invoke方法
    					@Override
    					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    						System.out.println("动态代理开始");
    						Object returnVal = method.invoke(target, args);//反射机制调用目标对象的方法
    						System.out.println("动态代理结束");
    						return returnVal;
    					}
    				});
    	}
    }
    //测试
    public class Client {
    	public static void main(String[] args) {
    		//创建目标对象
    		ITeacherDao target = new TeacherDao();
    
    		//创建代理对象
    		ITeacherDao proxyInstance = (ITeacherDao)new ProxyFactory(target).getProxyInstance();
    
    		//内存中动态生成了代理对象
    		System.out.println(proxyInstance.getClass());
    
    		//通过代理对象,调用目标对象的方法
    		proxyInstance.teach();
    		proxyInstance.test("一键三连");
    	}
    }
    

标签:target,对象,代理,模式,目标,设计模式,ITeacherDao,public
From: https://www.cnblogs.com/hytip/p/18189133

相关文章

  • 5分钟学设计模式:简单工厂与美食街的不期而遇
    大家好,我是知微。写代码好几年,是不是还纠结于这些问题:面对一堆if-else,代码越写越长,维护起来比攀登珠穆朗玛峰还难每次只敢小心翼翼改个小功能,生怕程序突然“嘭”一声,全炸了想学习大佬们的代码,却总是看得一头雾水,不知如何下手。别急,优秀的代码设计往往有秘诀——设计模式。......
  • distribution镜像仓库代理缓存
    本文在《学习distribution》之后,梳理一份基础的用于代理远端仓库的基础配置。配置需求镜像地址在远端定期清理缓存优先没有任何中间件服务需要健康检查需要暴露prometheus指标优先外部正式的HTTPS证书配置明细version:0.1log:level:debugfields:service......
  • 设计模式之单例模式
    单例模式提供了一种创建对象的最佳方式:这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。单例类只能有一个实例;单例类必须自己创建自己的唯一实例;单例类必须给......
  • 设计模式04----原型模式
    原型模式(PrototypePattern)是一种创建型设计模式,在软件工程中用来创建对象的副本,从而避免新建对象时的性能开销。此模式利用已存在的对象实例作为原型,通过克隆(Clone)机制来创建新的对象,新对象与原型对象具有相同的属性和状态,但彼此独立,修改一个对象不会影响到另一个。原理与特点......
  • 思维减负·系列:(七)重塑语言模式
          我们的语言模式对思维方式有着重要影响。重塑语言模式,避免使用消极、绝对化的语言,多使用积极乐观的语言表达,塑造积极心态,是远离过度思考和精神内耗的一个关键。      不要用恶毒的语言、负面的情绪和思维喂养自己的潜意识。对自己要有同情心,给自己美......
  • 生产者与消费者模式
    importthreadingfromqueueimportQueuefromrandomimportchoicedealList=["红烧猪蹄","卤鸡爪","酸菜鱼","糖醋里脊","九转大肠","阳春面","烤鸭","烧鸡","剁椒鱼头","酸汤肥牛",&quo......
  • 详解Redis持久化(持久化高危漏洞利用与多种对抗方案、RDB、AOF、同步手动持久化、异步
    谨防持久化+未授权访问漏洞入侵服务器CVE编号找不到,CNVD有一个:CNVD-2015-07557(国家信息安全漏洞共享平台漏洞编号)。这是我之前写过的文章,漏洞成因、影响范围、POC与对抗方案有详解:谨防利用Redis未授权访问漏洞入侵服务器RDB(RedisDatabase、全量保存,默认方式)极简概括:通过符......
  • 应用模式启动
    与单作业模式类似,直接执行flinkrun-application命令$bin/flinkrun-application-tyarn-application-ccom.huft.flk117.demo.StreamSocketCntjob_jar/original-fk117-1.0-SNAPSHOT.jar查看web及yarnid2.在命令行中查看或取消作业。$bin/flinklist-tyarn-applic......
  • 3-LVS工作模式
    3.LVS工作模式NAT  TUN  DRhttps://blog.csdn.net/weixin_40470303/article/details/80541639NAT1.LVS服务器配两块网卡,一块连公网与用户通信,一块连内网与集群通信2.负载路由器充当网关3.支持端口映射,后端真实服务器的地址可能不是80,而是80804.集群节点处于一个网络......
  • 会话模式启动
    YARN的会话模式与独立集群略有不同,需要首先申请一个YARN会话(YARNSession)来启动Flink集群。1.后台启动yarn会话模式flink集群bin/yarn-session.sh-d-nmtest2.查看返回地址和yarnidyarn会自动分配集群随机一台主机和端口号JobManagerWebInterface:http://xxx1:38005fl......