Kotlin~Proxy代理模式

概念

又称委托模式,充当中介代理的类。
特点:让一个对象控制另一个对象的访问,让代理充当其他事物的接口。

角色介绍

  • 抽象目标类
  • 具体目标类
  • 代理类

UML

在这里插入图片描述

代码实现

按实现分为静态和动态代理

interface PhoneSell {
    fun sell()
}

class MainPhoneSell : PhoneSell {
    override fun sell() {
        println("手机销售")
    }
}

静态代理

代理类拿到被代理实例后,调用被代理类的方法,同时可以对代理方法进行增强。

class ProxyPhoneSell : PhoneSell {
    private val mainPhoneSell = MainPhoneSell()
    override fun sell() {
        println("赚取200元服务费")
        mainPhoneSell.sell()
    }
}

动态代理

动态代理是java提供的一个动态代理类Proxy,通过它的方法newProxyInstance来创建代理实例。它有三个参数

  • loader(ClassLoader): 这个参数是实际被代理类的类加载器实例。
  • interfaces(Class[]): 代理类和被代理类共同实现的接口的Class数组。
  • h(InvocationHandler): 代理拦截器接口,一般需要使用子类去实现该接口或匿名类去实现。
class ProxyFactory {
    private val phoneSell = MainPhoneSell()
    fun getProxy() = Proxy.newProxyInstance(
        phoneSell.javaClass.classLoader,
        phoneSell.javaClass.interfaces
    ) { proxy, method, args ->
        println("收取200元服务费")
        method.invoke(phoneSell, *args.orEmpty())
    } as PhoneSell
}

分别调用

fun main() {
    ProxyPhoneSell().sell()
    ProxyFactory().getProxy().sell()
}

优缺点

优点:

  • 关注点分离
  • 访问控制
  • 延迟实例化
  • 远程访问
  • 缓存
  • 扩展额外的行为

缺点:

  • 增加复杂性
  • 间接性
  • 性能开销

应用场景

按职责来划分,通常有以下使用场景:

  1. 远程代理:根据用户的访问权限控制对实际对象的访问
  2. 虚拟代理:需要使用时才创建它,类似于by lazy
  3. Copy-on-Write代理
  4. 保护(Protect or Access)代理
  5. Cache代理:缓存对象操作结果
  6. 防火墙(Firewall)代理
  7. 同步化(Synchronization)代理
  8. 智能引用(Smart Reference)代理
    还可用于日志记录、监控和审计。

总结

静态代理比较简单,但代码的维护和复用上还是动态代理好一点。
注意事项:

  1. 和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
  2. 和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

这里有一个面试题:动态代理为什么只能基于接口?
因为它使用的是Java中的反射机制来创建代理对象。在Java中,类可以通过实现接口来达到多态的效果。因此,JDK动态代理要求目标对象必须实现至少一个接口,这样才能通过反射获取到目标对象实现的接口列表,进而动态地创建代理类。具体来说,JDK动态代理是通过实现目标接口的方式来创建代理类的,代理类会实现目标接口中定义的所有方法,并在代理类中通过反射调用目标对象的方法,从而完成代理的功能。因此,如果目标对象没有实现任何接口,那么JDK动态代理就无法生成代理类。
参考:

  • 当Kotlin邂逅设计模式之代理模式(二)
  • 代理模式

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

4K/8K AI巡检详解:风电巡检领域主动出击的监控厂商

最近,“北方高温”、“厄尔尼诺大烤”等词条频上热搜的背后,为应对气候变化挑战,全球正迎来一场波澜壮阔的绿色低碳转型浪潮。 而在“碳达峰、碳中和”政策背景下,风电行业肩负着重要的责任与使命。根据《中国可再生能源发展报告…

【JavaEE】基于Servlet与MySQL实现一个简易网站

目录 前言 一、实现表白墙的前期准备工作 1、约定前后端交互的接口 1.1、接口一:页面获取当前所有的留言消息 1.2、接口二:提交新消息给服务器 二、前端和后端代码的实现 1、数据的永久化保存 2、小结 前言 之前小编在写前端页面的时候&#x…

SkyWalking链路追踪中span全解

基本概念 在SkyWalking链路追踪中,Span(跨度)是Trace(追踪)的组成部分之一。Span代表一次调用或操作的单个组件,可以是一个方法调用、一个HTTP请求或者其他类型的操作。 每个Span都包含了一些关键的信息&am…

1.前端入门

文章目录 一、基础认知1.1 认识网页:1.2 五大浏览器1.3 Web标准 总结 提示:以下是本篇文章正文内容,下面案例可供参考 一、基础认知 1.1 认识网页: 1.网页由哪些部分组成? 文字、图片、音频、视频、超链接。 2.我们…

(五)FLUX中的数据类型

以下内容来自 尚硅谷,写这一系列的文章,主要是为了方便后续自己的查看,不用带着个PDF找来找去的,太麻烦! 第 5 章 FLUX中的数据类型 5.1 10 个基本数据类型 5.1.1 Boolean (布尔型) 5.1.1.1 …

sql进阶 之case表达式

case表达式 CASE表达式是SQL里非常重要而且使用起来非常便利的技术,我们应该学会用它来描述条件分支。本节将通过行列转换、已有数据重分组(分类)、与约束的结合使用、针对聚合结果的条件分支等例题,来介绍CASE表达式的用法。标红…

JAVA设计模式——23种设计模式详解

一、什么是设计模式🍉 设计模式(Design pattern) 是解决软件开发某些特定问题而提出的一些解决方案也可以理解成解决问题的一些思路。通过设计模式可以帮助我们增强代码的可重用性、可扩充性、 可维护性、灵活性好。我们使用设计模式最终的目…

MATLAB与ROS联合仿真——ROS环境搭建及相关准备工作(上)

本篇文章主要介绍在安装完ROS后,在进行MATLAB与ROS联合仿真之前,需要进行的一些环境搭建以及准备工作,主要分为 创建ROS工作空间及功能包、必备功能包安装、安装Gazebo11、导入实验功能包至工作空间、安装Visual_Studio_Code(选做)、常用便捷…

mac端数据库管理 Navicat Premium 15 for Mac v15.0.36

Navicat Premium 15是一款功能强大的数据库管理工具,由PremiumSoft CyberTech Ltd.开发。它提供了一个集成的界面,用于连接和管理多种不同类型的数据库,如MySQL、Oracle、SQL Server、PostgreSQL等。 Navicat Premium 15具有直观和用户友好的…

NFT和数字藏品的安全方案解析

一、NFT和数字藏品 01 NFT是什么? NFT 是Non-Fungible Tokens 的缩写,意思是不可互换的代币,它是相对于可互换的代币而言的。不可互换的代币也称为非同质代币。什么是可互换的代币?比如BTC(比特币)、ETH&…

SDN系统方法 | 5. 交换机操作系统

随着互联网和数据中心流量的爆炸式增长,SDN已经逐步取代静态路由交换设备成为构建网络的主流方式,本系列是免费电子书《Software-Defined Networks: A Systems Approach》的中文版,完整介绍了SDN的概念、原理、架构和实现方式。原文: Softwar…

react native 本地存储 AsyncStorage

An asynchronous, unencrypted, persistent, key-value storage system for React Native. Async Storage 只能用来储存字符串数据,所以为了去储存object类型的数据,得先进行序列化(JSON.stringify())当你想要使用数据的时候&…

低代码:“提效降本”是如何炼成的

人们向往着从前车马慢的生活,可对于工厂而言,慢节奏如同噩梦。 目录 01、低代码的到来 02、让开发提效降本 03、结束语 在没有数字化以前的制造业,多个厂区之间的信息传递,例如采购单或者审批单,要用货车拉&#xff0c…

Keepalived热备、Keepalived+LVS、HAProxy监控及后端服务器健康检查、负载均衡调度器对比

day02 day02KeepAlived高可用集群配置高可用的web集群监控本机80端口,实现主备切换实现原理实施配置高可用、负载均衡的web集群配置高可用、负载均衡HAProxy配置haproxy负载均衡调度器比较LVS(Linux Virtual Server)NginxHAProxy KeepAlive…

iptables 防火墙

防火墙:隔离功能 部署在网络边缘或者主机边缘,在工作中,防火墙的主要作用,决定哪些数据可以被外网使用,以及哪些数据可以进入内网访问 主要工作在网络层 安全技术 1.入侵检测系统:检测出威胁&#xff0…

【后端面经】微服务构架 (1-3) | 熔断:熔断-恢复-熔断-恢复,抖来抖去怎么办?

文章目录 一、前置知识1、什么是熔断?2、什么是限流?3、什么是降级?4、怎么判断微服务出现了问题?A、指标有哪些?B、阈值如何选择?C、超过阈值之后,要不要持续一段时间才触发熔断?5、服务恢复正常二、面试环节1、面试准备2、面试基本思路三、总结 在微服务构架中…

【业务功能篇50】ObjectMapper-将java对象转为json字符串

ObjectMapper可以实现Java对象和json字符串间互相转换,我们经常用到的是它的Java对象转json字符串功能。 这里目的是 Java对象 json字符串相互转换 api 【json字符串转为Java对象:readValue(json字符串,类.class)】【Java对象转为json字符串&#xff1a…

WPF实战学习笔记09-创建工作单元

创建工作单元 添加包 Microsoft.EntityFrameworkCore.AutoHistory A plugin for Microsoft.EntityFrameworkCore to support automatically recording data changes history. Microsoft.EntityFrameworkCore.UnitOfWork A plugin for Microsoft.EntityFrameworkCore to suppor…

Python实战项目——旅游数据分析(四)

由于有之前的项目,所以今天我们直接开始,不做需求分析,还不会需求分析的可以看我之前的文章。Python实战项目——用户消费行为数据分析(三) 导入库 import numpy as np import pandas as pd import matplotlib.pyplo…

Canal深入调研

Canal深入调研 1.canal的设计 1.1 Canal的设计理念 canal的组件化设计非常好,有点类似于tomcat的设计。使用组合设计,依赖倒置,面向接口的设计。 说明: ​ server代表一个canal运行实例,对应于一个jvm ​ instance…