设计模式结构型模式之代理模式

news2024/11/16 3:40:00

结构型模式之代理模式

  • 一、概念和使用场景
    • 1、概念
    • 2、核心思想
    • 3、java实现代理模式的方式
    • 4、使用场景
  • 二、示例讲解
    • 1. 静态代理
    • 2. 动态代理
  • 三、总结
    • 1、使用规则
    • 2、代理模式的优点包括:
    • 3、代理模式的缺点包括:

一、概念和使用场景

1、概念

代理模式是一种结构型设计模式,它允许我们为其他对象提供一个代理或者占位符,以控制对该对象的访问。

2、核心思想

代理模式的核心思想是在访问一个对象时引入一个代理对象,通过代理对象来控制访问的权限和行为。代理对象和被代理对象具有相同的接口,这样客户端就可以通过代理对象来访问被代理对象。代理对象可以拦截对被代理对象的访问,并添加额外的逻辑,例如权限检查、缓存等。

3、java实现代理模式的方式

在Java中实现代理模式有两种方式:静态代理和动态代理

4、使用场景

Java代理模式的使用场景有以下几个:

  1. 远程代理:当对象存在不同地址空间时,可以使用远程代理来隐藏对象的具体实现细节,使得客户端可以像访问本地对象一样访问远程对象。远程代理主要用于网络通信中的远程方法调用。

  2. 虚拟代理:当创建一个对象需要很长时间时(例如加载大量数据或者进行复杂的计算),可以使用虚拟代理来延迟对象的创建。虚拟代理在真正需要使用对象时才会创建,可以节省系统资源。

  3. 安全代理:当需要控制对某个对象的访问权限时,可以使用安全代理来限制对对象的直接访问。安全代理可以在访问对象之前进行权限验证,确保只有具有相应权限的用户才能访问对象。

  4. 缓存代理:当需要缓存对象的结果时,可以使用缓存代理来提高系统的性能。缓存代理会在调用对象的方法之前检查缓存,如果缓存中已经存在相同的结果,则直接返回缓存中的结果,而不去真正执行方法。

  5. 日志记录代理:当需要记录对象的操作日志时,可以使用日志记录代理来实现。日志记录代理会在调用对象的方法之前进行日志记录,可以记录下对象的操作信息,方便后续的审计和分析。

总之,代理模式可以在不改变原有对象的情况下,通过引入代理对象来增加一些额外的功能,提供更好的控制和封装。

二、示例讲解

1. 静态代理

静态代理是在编译时就已经确定代理对象的类型,代理对象和被代理对象都需要实现同一个接口。代理对象在调用被代理对象的方法前后可以执行一些额外的逻辑。

下面是一个简单的静态代理的示例代码:
定义一个接口 SaleHouse

//待出售房产
public interface SaleHouse {

    //房产信息
    Object    houseInformation(String price);
}

被代理的角色(房子主人) HouseOwner

package org.storemanage.regestercenter.proxymode;

/**
 * @CreateTime: 2024-08-30
 * @Description: 房屋主人
 * @Version: 1.0
 * @Author: hkf
 */

public class HouseOwner implements SaleHouse {

    private final String  name ="阳光别墅区";

    private final  String address ="四川省成都市武侯区双楠大道xxx小区123号";

    private String price;
    @Override
    public Object houseInformation(String price) {
        String  houseInfo ="200 W";
        if (!price.isEmpty()) {
           houseInfo=  "房产名称:"+name+"\n 地址为:"+address+"\n房产价格为:"+price;
        }
        return houseInfo ;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "HouseOwner{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", price='" + price + '\'' +
                '}';
    }
}

代理角色 (房屋中介) HouseAgent

package org.storemanage.regestercenter.proxymode;

/**
 * @CreateTime: 2024-08-30
 * @Description: 房屋中介
 * @Version: 1.0
 * @Author: hkf
 */

public class HouseAgent implements SaleHouse {

   private   String  price;

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    HouseOwner  houseOwner;


    //中介为了赚佣金,提高了出售的价格
    @Override
    public Object houseInformation(String price) {
         Object houseInfo ="";
        if (houseOwner == null) {
            houseOwner = new HouseOwner();
             houseInfo = houseOwner.houseInformation(price);
        }
        return houseInfo;
    }

    @Override
    public String toString() {
        return "HouseAgent{" +
                "price='" + price + '\'' +
                ", houseOwner=" + houseOwner +
                '}';
    }
}

客户端调用者 ClientHouseAgent

package org.storemanage.regestercenter.proxymode;

/**
 * @CreateTime: 2024-08-30
 * @Description: 客户端代理实现
 * @Version: 1.0
 * @Author: hkf
 */

public class ClientHouseAgent {
    public static void main(String[] args) {
        HouseAgent houseAgent = new HouseAgent();
        //中介可以自定义价格,赚取佣金
        Object houseInfo = houseAgent.houseInformation("236 w");

        System.out.println(houseInfo);
    }

}

结果如图
在这里插入图片描述

2. 动态代理

动态代理是在运行时通过反射机制动态生成代理对象,代理对象不需要实现接口,但需要指定一个接口或者父类来实现代理。

下面是一个简单的动态代理的示例代码:

定义接口 SaleHouse

package org.storemanage.regestercenter.proxymode;

//待出售房产
public interface SaleHouse {

    //房产信息
    Object    houseInformation(String price);
}

定义被代理角色 HouseOwner

package org.storemanage.regestercenter.proxymode;

/**
 * @CreateTime: 2024-08-30
 * @Description: 房屋主人
 * @Version: 1.0
 * @Author: hkf
 */

public class HouseOwner implements SaleHouse {

    private final String  name ="阳光别墅区";

    private final  String address ="四川省成都市武侯区双楠大道xxx小区123号";

    private String price;
    @Override
    public Object houseInformation(String price) {
        String  houseInfo ="200 W";
        if (!price.isEmpty()) {
           houseInfo=  "房产名称:"+name+"\n 地址为:"+address+"\n房产价格为:"+price;
        }
        return houseInfo ;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "HouseOwner{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", price='" + price + '\'' +
                '}';
    }
}

创建代理角色 HouseAgentInvocationHandler

package org.storemanage.regestercenter.proxymode;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @CreateTime: 2024-08-30
 * @Description: 中介动态代理
 * @Version: 1.0
 * @Author: hkf
 */

public class HouseAgentInvocationHandler implements InvocationHandler {

    private Object  target;
    public HouseAgentInvocationHandler(Object  target){
        this.target = target;

    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method: " + method.getName());
        Object invoke = method.invoke(target, args);
        System.out.println(" After  method: " + method.getName());
        return invoke;
    }
}

客户端代码 ClientHouseDemo

package org.storemanage.regestercenter.proxymode;

import java.lang.reflect.Proxy;

/**
 * @CreateTime: 2024-08-30
 * @Description: 动态代理客户端代码
 * @Version: 1.0
 * @Author: hkf
 */

public class ClientHouseDemo {
    public static void main(String[] args) {
        HouseOwner houseOwner = new HouseOwner();
        HouseAgentInvocationHandler handler = new HouseAgentInvocationHandler(houseOwner);
       SaleHouse saleHouse=(SaleHouse)Proxy.newProxyInstance(houseOwner.getClass().getClassLoader(), houseOwner.getClass().getInterfaces(),handler
              );
        Object o1 = saleHouse.houseInformation("443 W");
        System.out.println(o1);

    }
}

结果如图
在这里插入图片描述
在上述代码中,我们首先定义了一个接口 SaleHouse ,然后实现了该接口的具体类 HouseOwner 。接着,定义了 HouseAgentInvocationHandler 类作为动态代理的 InvocationHandler ,在 invoke 方法中可以添加额外的逻辑。在客户端代码中,我们创建了 HouseOwner 对象和 HouseAgentInvocationHandler 对象,然后利用 Proxy 类的 newProxyInstance 方法生成代理对象,最后调用代理对象的 houseInformation 方法。

三、总结

1、使用规则

无论是静态代理还是动态代理,代理模式都可以在不改变被代理对象的情况下,对访问进行控制和添加额外的逻辑。代理模式可以提高代码的可维护性和可扩展性,但也会增加代码的复杂性和性能开销,因此在使用代理模式时需要根据具体的情况进行权衡。

2、代理模式的优点包括:

  1. 代理模式可以实现真实对象的延迟加载。当真实对象的创建和初始化过程比较耗时时,使用代理模式可以在需要的时候才创建真实对象,提高系统的性能和响应速度。

  2. 代理模式可以提供额外的安全性控制。通过代理对象来控制对真实对象的访问,可以在访问前后进行一些额外的安全性检查和操作,增加系统的安全性。

  3. 代理模式可以实现对真实对象的访问控制和管理。通过代理对象可以控制对真实对象的访问和调用,可以实现一些额外的管理功能,如权限控制、缓存管理等。

3、代理模式的缺点包括:

  1. 代理模式增加了系统的复杂度。引入代理对象会增加系统中的类和对象的数量,增加系统的复杂度和维护成本。

  2. 代理模式可能会引入性能问题。由于代理模式引入了额外的层次,可能会在一定程度上降低系统的性能,特别是在频繁访问真实对象的情况下。

  3. 代理模式的设计需要考虑到代理对象和真实对象之间的接口的一致性,使得系统的设计和实现更加复杂。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

低配电脑也能玩《黑神话:悟空》,上Finovy Cloud白嫖4090云桌面!

猿神!启动! 各位天命人,大家都玩上《黑神话:悟空》了吗?玩上的友友,又几周目了呢? 20号刚上线,《黑神话:悟空》火速攻上了微博热搜第一,网上的评论也层出不…

家里养宠物空气净化器有用吗?哪款最值得推荐?

家里养了一只猫和一条狗,幸福感翻倍上升。首先就是它能在这座城市给我极大的安慰,每次都不知道应该向谁诉说难过的时候,它们总能给我极大的安慰。它们除了给我安慰,还会给我带来新的朋友,毕竟自己一个人来到一座城&…

封装信号灯集相关API

由信号灯实现通信。 发送端send.c代码&#xff1a; #include <myhead.h> #include "./sem.h" #define PAGE_SIZE 4096 int main(int argc, const char *argv[]) {int semid semID_get(2);//创建2个信号灯key_t key ftok("./",U);if(key-1){perro…

书籍销售系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;书籍分类管理&#xff0c;书籍信息管理&#xff0c;订单管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;书籍信息&#xff0c;书籍资讯&#xff0…

互联网人+大模型=?

外界看互联网人和大模型的关系 是“你有这么高速运转的互联网人 搭载了大模型记住我给出的原理” 而实际上大模型的出现 让原本整齐划一说黑话的互联网人 分裂出了各种派别 朋友&#xff0c;现在是大模型乱纪元&#xff0c; 而你&#xff0c;又是哪一派呢&#xff1f; —…

【C++ Primer Plus习题】7.2

问题: 解答: #include <iostream> using namespace std;#define MAX 10int input(float* grade, int len) {int i 0;for (i 0; i < len; i){cout << "请输入第" << i 1 << "个高尔夫成绩(按0结束):";cin >> grade[i]…

【读点论文】Text detection and localization in scene images: a broad review

Text detection and localization in scene images: a broad review Abstract 如今&#xff0c;文本检测和定位在文本分析系统领域已广受欢迎&#xff0c;因为它们为大量实时应用铺平了道路&#xff0c;例如移动音译技术、视障人士辅助方法等。 文本检测和定位技术用于查找图…

过滤器和拦截器的使用和原理

1. 过滤器和拦截器 过滤器(Filter) 拦截器(Interceptor) 1.1 区别 过滤器和拦截器触发时机不一样, 过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前拦截器可以获取IOC容器中的各个bean,而过滤…

科研项目经费管理,降本增效的不二之选

国内外主流的 10 款科研项目经费管理系统对比&#xff1a;PingCode、Worktile、Colloa科研项目管理平台、云科研管理系统、智方科研管理系统、NIH Grants、NSF – National Science Foundation、IDRC、Bill & Melinda Gates Foundation、Canadian Institutes of Health Res…

媲美Flux pro! Ideogram 发布了 2.0 图像生成模型, 照片级真实感和高质量文本渲染!

Ideogram 发布了 2.0 模型,图像生成质量大幅提高&#xff0c;产品易用性改善&#xff0c;文字生成能力也提升许多。Ideogram 2.0 在图像快速对齐、照片级真实感和文本渲染质量方面取得了显著进步。人工评估一致认为 Ideogram 2.0 比 Flux Pro 和 DALLE 3 有了显著改进。尽管我们…

人工智能的可解释性(XAI) | 使用LIME

人工智能&#xff08;AI&#xff09;的广阔领域近年来经历了巨大的增长。随着每年更新、更复杂的模型问世&#xff0c;人工智能模型已经开始以无人能预测的速度超越人类智力。但是&#xff0c;随着我们得到更准确和精确的结果&#xff0c;解释这些模型所采取的复杂数学决策背后…

[翻译+笔记] 用于视频生成的Diffusion Model

这次翻译笔记的博客是https://lilianweng.github.io/posts/2021-07-11-diffusion-models/ 在阅读这篇博客前, 推荐先对Diffusion Model进行了解. 可以看我的笔记: https://blog.csdn.net/wjpwjpwjp0831/article/details/141524088 视频相关的任务向来是比图像更有挑战性, 这是…

涉密载体管控系统DW-S402|实现载体全寿命管控

为加强涉密载体使用管控&#xff0c;按照预防为主&#xff0c;强化监督&#xff0c;在满足各级保密规定前提下&#xff0c;方便涉密载体的使用和管理&#xff0c;确保涉密载体保密安全。 现有涉密载体使用过程中&#xff0c;存在手工登记台账耗工耗时、领用情况不直观、违规带…

史上最全Android UI界面设计尺寸!点击收藏

作为一名 UI 设计师&#xff0c;在进行 Android UI 设计之前&#xff0c;首先需要明确 Android 系统与 iOS 系统之间的主要区别。Android 系统是开源的&#xff0c;而 iOS 系统则是不开源的。虽然 Android 系统的开源特性对于交互设计师是有益的&#xff0c;但它也带来了一些挑…

白立新谈命运三重奏:《黑神话:悟空》中的人生思考

文 | 头部财经首席评论员白立新 发布 | 头部财经 top168.com 导语&#xff1a;《黑神话&#xff1a;悟空》中三个悟空形象演绎命运三种属性。老者悟空象征确定性&#xff0c;历经沧桑&#xff0c;蕴含世界法则&#xff1b;玩家操作悟空代表能动性&#xff0c;承载玩家意志影响…

seaborn:一个超炫的数据可视化Python库

我是东哥&#xff0c;专注于分享Python技术的自媒体人。今天&#xff0c;我将带你深入了解一个非常有趣的Python库——Seaborn。无论你是刚入门的Python小白&#xff0c;还是希望提升数据可视化技能的技术小白&#xff0c;相信这篇文章都会对你有所帮助。 项目地址&#xff1a…

数学符号-西格玛

西格玛”是希腊字母&#xff0c;也有念作“西玛”“希玛”等各种读法&#xff0c;符号是∑,英文译音是Sigma, 表示数学中的求和号&#xff0c;是数学中常用的符号&#xff0c;主要用于求多项数的和&#xff0c;用∑表示 ∑下面的小字,如i1表示从i1开始求和 上面的小字&#xf…

【网络世界】网络层

目录 &#x1f308;前言&#x1f308; &#x1f4c1; 网络层 &#x1f4c1; IPV4 &#x1f4c2; 什么是IP地址 &#x1f4c2; 网段划分 &#x1f4c2; 特殊IP &#x1f4c2; 内网和公网 &#x1f4c2; IPV4的危机 &#x1f4c1; IP协议格式 &#x1f4c1; 路由 &#x1f…

【工具篇】高效记忆方法之AnKi工具

&#x1f60a;你好&#xff0c;我是南极。正在变强的路上不断地努力着&#x1f4aa; &#x1f514;今天和大家分享一些记忆的方法&#xff0c;以及推荐了一款用于复习和巩固知识的软件AnKi。 对我们程序员而言&#xff0c;平常学习的东西会比较多&#xff0c;有时呢学的东西会…

气势向前,豪华向上 全新BMW X3长轴距版全球首发,更大体量、更高价值、更多驾趣

X家族的中流砥柱&#xff0c;豪华中型SAV的引领者现代极简主义&#xff0c;原石切割般的型面&#xff0c;塑造纯粹的BMW X辨识度“以驾驶员为中心”和“以简释繁”&#xff0c;打造“中国专属”的精致豪华空间创新不止&#xff0c;驾趣依旧&#xff0c;探索未知的忠实伙伴 &…