首页 > 编程语言 >程序员必知!代理模式的实战应用与案例分析

程序员必知!代理模式的实战应用与案例分析

时间:2024-01-09 13:32:07浏览次数:28  
标签:实战 调用 Service 必知 代理 RealService 程序员 对象 public

程序员必知!代理模式的实战应用与案例分析 - 程序员古德

代理模式是在不改变原对象基础上,通过代理对象控制访问并添加额外操作,以销售代表和助理为例,助理作为代理对象,处理邮件、数据等琐碎工作,使销售代表能专注于与客户面对面交流推销,代理模式让原对象功能得以扩展,同时保持其对外接口的透明性。

定义

程序员必知!代理模式的实战应用与案例分析 - 程序员古德

代理模式提供了一种在不改变原有对象的情况下,为另一个对象提供一种代理或占位符的方式,代理对象可以控制对原有对象的访问,并可以在访问过程中添加额外的操作,例如记录日志、进行权限验证等。

举一个业务中形象的例子来说明代理模式,假设你是一家公司的销售代表,你负责与客户沟通并推销公司的产品,为了更好地与客户沟通,公司决定为你聘请一位助理,这位助理可以帮你处理一些繁琐的工作,比如回复客户的邮件、整理销售数据等,这样,你就可以专注于与客户进行面对面的交流和推销。在这个例子中,助理就是代理对象,它帮助你处理了一些琐碎的工作,让你能够专注于销售工作,同时,你仍然可以直接与客户进行沟通,并不会改变原有的销售代表角色。

代码案例

程序员必知!代理模式的实战应用与案例分析 - 程序员古德

下面是一个反例,说明了未使用代理模式时的代码结构,其中客户端直接调用一个服务类的方法,没有任何代理在中间进行拦截或添加额外功能。

首先,我们定义一个服务接口Service和它的实现类RealService,如下代码:

// 服务接口  
public interface Service {  
    void performAction();  
}  
  
// 真实的服务实现类  
public class RealService implements Service {  
    @Override  
    public void performAction() {  
        System.out.println("RealService is performing an action.");  
    }  
}

接下来,我们写一个客户端类Client,它直接实例化RealService并调用其方法,如下代码:

// 客户端类,直接调用RealService  
public class Client {  
    public static void main(String[] args) {  
        // 客户端直接创建RealService的实例并调用其方法  
        Service service = new RealService();  
        service.performAction(); // 输出: RealService is performing an action.  
    }  
}

在这个例子中,没有使用代理模式,当客户端需要执行某个操作时,它直接创建RealService的实例并调用其performAction()方法,输出结果如下:

RealService is performing an action.

假设,现在我们想要在调用服务方法之前添加一些前置操作,比如日志记录或安全检查,由于我们没有使用代理模式,我们不得不在RealService类中添加这些逻辑,这可能会破坏类的单一职责原则,并且不易于维护和扩展,而如果我们使用了代理模式,就可以在不修改原有服务类的情况下,通过代理类来添加这些额外的功能。

下面是一个使用代理模式的正例代码,我们引入一个代理类,该类实现与服务类相同的接口,并在其内部持有一个对服务类实例的引用,代理类可以在调用服务类的方法之前或之后执行额外的操作,如日志记录、权限检查等。

首先,我们定义一个服务接口Service和它的实现类RealService,如下代码:

// 服务接口  
public interface Service {  
    void performAction();  
}  
  
// 真实的服务实现类  
public class RealService implements Service {  
    @Override  
    public void performAction() {  
        System.out.println("RealService is performing an action.");  
    }  
}

然后,我们创建一个代理类ServiceProxy,它同样实现了Service接口,并持有一个RealService的引用,如下代码:

// 代理类,实现了Service接口并持有RealService的引用  
public class ServiceProxy implements Service {  
    private Service realService; // 持有真实服务类的引用  
  
    public ServiceProxy(Service realService) {  
        this.realService = realService;  
    }  
  
    @Override  
    public void performAction() {  
        System.out.println("Proxy: Preparing to perform action."); // 前置操作  
        realService.performAction(); // 调用真实服务类的方法  
        System.out.println("Proxy: Action has been performed."); // 后置操作  
    }  
}

最后,我们写一个客户端类Client,它使用代理类来间接调用真实的服务类,如下代码:

// 客户端类,使用代理来调用服务  
public class Client {  
    public static void main(String[] args) {  
        // 创建真实服务类的实例  
        Service realService = new RealService();  
        // 创建代理类的实例,并将真实服务类的实例传入  
        Service proxyService = new ServiceProxy(realService);  
        // 通过代理类调用方法  
        proxyService.performAction();  
        // 输出结果将包括代理类的前置和后置操作信息  
    }  
}

输出结果如下:

Proxy: Preparing to perform action.  
RealService is performing an action.  
Proxy: Action has been performed.

在这个例子中,客户端通过代理类ServiceProxy来调用服务,代理类在调用真实服务类的方法之前和之后执行了额外的操作,这种方式允许我们在不修改原有服务类的情况下增加新的功能或控制流程。

本章节拓展知识点:

在Spring中AOP的实现以及事务管理也都是基于代理模式实现的。Spring AOP允许开发者定义横切关注点,这些关注点可以在不修改原有代码的情况下,对程序进行增强,它通过使用代理对象,在目标方法执行前后或出现异常时,织入额外的逻辑,如日志记录、事务管理、安全控制等;Spring中的事务管理会为目标对象创建一个代理对象,这个代理对象会在目标方法执行时开启事务,并在方法执行完成后提交或回滚事务,通过这种方式,Spring实现了声明式事务管理,使得开发者可以专注于业务逻辑的开发,而无需关心事务的细节。

核心总结

程序员必知!代理模式的实战应用与案例分析 - 程序员古德

代理模式是一种常用的设计模式,它通过引入代理对象来控制对目标对象的访问,增加额外的功能或控制,其优点主要在于:能够在不修改原有代码的基础上增强功能,实现对真实对象的保护和隐藏;提高系统的灵活性和可扩展性,降低耦合度。其缺点主要在于:会增加系统的复杂性和额外的开销,因为需要创建和维护代理类;同时,如果过度使用代理模式,可能会导致系统结构变得复杂和难以理解。

本章节拓展知识点:

代理模式通常会和装饰器模式搞混淆,这两种设计模式在结构上有一定的相似性,因为它们都涉及到一个对象包装另一个对象,并在调用被包装对象的方法时添加一些额外的逻辑。

代理模式的主要目的是控制对另一个对象的访问,它可以添加一些前置或后置的处理逻辑,比如权限检查、日志记录等;;;而装饰器模式的主要目的是动态地给一个对象添加额外的职责或功能,它通过在调用原始对象的方法之前或之后执行一些操作来实现这一点。

尽管两者有一些相似之处,但它们的目的和用法是不同的,代理模式更多地关注于控制访问,而装饰器模式则更多地关注于动态地添加功能。

关注我,每天学习互联网编程技术 - 程序员古德

完!

标签:实战,调用,Service,必知,代理,RealService,程序员,对象,public
From: https://blog.51cto.com/bytegood/9160878

相关文章

  • 程序员如何准备好一次高质量的汇报?
    又到一年年末时,相信大家都希望在年终汇报的时候,能给老板展示一下自己女娲补天般的业绩,但很多人却往往讲成了流水账,本来90分的成绩,从嘴里说出来变成了60分。(文末附述职PPT模版下载)同事们普遍都觉得你做的很好,但是汇报过程中,你却发现语言讲不通、功劳说不清,该讲的不讲,不该讲的......
  • AWS IoT Core 实战指南
    AmazonWebServices(AWS)提供了全球范围内的托管服务,其中包括AWSIoTCore,专为连接和管理物联网设备而设计。这个实战指南将带你一步步了解如何使用AWSIoTCore来注册设备、提高安全性、进行通信以及利用设备影子功能。设备注册1.创建Thing(设备)在AWSIoT控制台中,创建一......
  • 低代码开发中的文件上传与数据处理:实战指南
    在当今的信息化时代,数据已成为企业的重要资产。为了更好地管理和利用这些数据,许多企业开始采用表单上传组件来导入和处理数据。通过使用表单上传组件,用户可以方便地将文件上传至系统中,然后进行后续的数据处理和分析。这种方式的优点在于,用户无需掌握复杂的编程技术,即可完成数据导入......
  • 《PySpark大数据分析实战》-10.独立集群模式的代码运行
    ......
  • 闪速优选--五天学会SpringCloud实战
    本专栏带你用SpringCloudAlibaba搭建一套项目,让你五天掌握微服务的使用。微服务是很重要的技术,学会微服务会大大提升个人竞争力,大大提高简历筛选和面试通过率。项目名字:闪速优选。SpringCloudAlibaba在2020年之后的微服务项目中占主流,学它是最好的选择。教程地址:SpringCloud项目......
  • 十年老程序员运营第一个万粉
    知乎twitter背景上学的时候,认识一些朋友,他们都在记录一些技术内容,后来也跟他们学习,在一些平台学习记录。出来工作后,内容运营有些方向性,我一开始就打算学习大数据方面,所以写作方向是大数据AI方面。分析应用开发:刚入行时候就没有兴趣。游戏开发:小时候父亲就是卖游戏软件方面,初中以后......
  • Lua网络爬虫实战:使用http服务器获取虾皮商品信息的全过程
    这段Lua代码是一个简单的爬虫示例,使用了Lua中的http模块进行网络请求,并设置了代理信息。以下是对代码的一些解释和注意事项:安装http模块:luarocksinstallhttp这个命令用于安装Lua的http模块,以便在程序中使用HTTP请求功能。代理设置:localproxy_host="www.duoip.cn......
  • 文心一言实战大全
    "文心一言"是一款基于人工智能的写作助手,它能够协助用户生成多种类型的文本。以下是一些使用"文心一言"的实战示例:写博文如果你是博客作者,"文心一言"可以帮助你轻松生成博文。只需输入你的主题或关键词,它将生成一篇相关的博文。你可以直接使用生成的博文,也可根据需要进行编辑和修改......
  • 《PySpark大数据分析实战》-09.Spark独立集群安装
    ......
  • 2023年总结:一个普通程序员如何挑选出价值千万的职业赛道
    引言随着2023年的序幕缓缓落下,我终于在岁月的流转中捕捉到了一条隐秘而又公开的真理。它悄然告诉我们,成功并非单纯由勤劳的双手雕琢,一份耕耘未必有一份收获,而是在于我们如何在命运的十字路口作出关键选择。那句耳熟能详的“选择比努力重要”背后蕴藏着更深层意义。一起探寻如何才能......