【Java设计模式】结构型设计模式-代理模式(十)

代理模式

代理模式是指由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

进一步阐述:代理模式的结构比较简单,主要是通过定义一个继承抽象主题的代理来包含真实主题,从而实现对真实主题的访问,本质上代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用。 代理模式包含三种角色:

  • Subject(抽象主题):通过接口或抽象类声明真实主题和代理对象实现的业务方法。
  • Real Subject(真实主题):实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
  • Proxy(代理):提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

案例:我们以金士顿内存条代理商为例,金士顿是内存条的生产商,但有无数个代理商卖金士顿的内存条,代理商对客户开放,客户给与购买价格后,代理商赚取差价,但客户是不知道真实的价格的。

UML类图:

客户端Client类:

java 复制代码
/**
 * 使用代理模式的客户端(模拟用户购买金士顿内存条)
 */
public class Client {
​
    public static void main(String[] args) {
        //客户向内存条代理商给了150元购买内存条
        MemoryModuleProxy memoryModuleProxy = new MemoryModuleProxy();
        memoryModuleProxy.sell(150);
    }
}

内存条MemoryModule接口:

java 复制代码
/**
 * 内存条接口(抽象主题)
 */
public interface MemoryModule {
​
    /**
     * 出售内存条的方法
     */
    void sell(int money);
}

金士顿内存条KingstonMemoryModule类:

java 复制代码
/**
 * 金士顿内存条(真实主题)
 */
public class KingstonMemoryModule implements MemoryModule {
​
    @Override
    public void sell(int money) {
        System.out.println("金士顿厂商以" + money +  "的金额出售内存条");
    }
}

内存条代理商MemoryModuleProxy类:

java 复制代码
/**
 * 内存条代理商(代理)
 */
public class MemoryModuleProxy implements MemoryModule {
​
    /**
     * 持有金士顿内存条对象
     */
    private KingstonMemoryModule kingstonMemoryModule = new KingstonMemoryModule();
​
    @Override
    public void sell(int money) {
        preSell(money);
​
        //调用金士顿内存条的销售方法,默认金士顿厂商100元
        kingstonMemoryModule.sell(100);
​
        postSell(money);
    }
​
    /**
     * 打印代理商收取用户的钱(私有方法,让客户不可见)
     */
    private void preSell(int money) {
        System.out.println("代理商收取了客户" + money + "元钱");
    }
​
    /**
     * 打印代理商赚的钱(私有方法,让客户不可见)
     */
    private void postSell(int money) {
        System.out.println("代理商赚取了客户" + (money - 100) + "元钱");
    }
}

总结:

  • 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用。
  • 代理对象可以扩展目标对象的功能。代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性。
  • 代理模式会造成系统设计中类的数量增加,在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;增加了系统的复杂度。

典型运用场景举例: 当无法或不想直接引用某个对象或访问某个对象存在困难时,可以通过代理对象来间接访问。使用代理模式主要有两个目的: 一是保护目标对象,二是增强目标对象。例如:Spring AOP中就是基于代理模式来做到方法的增强,但使用的是动态代理技术。代理模式本身属于静态代理技术,动态代理是静态代理的升级。

相关推荐
善良勤劳勇敢而又聪明的老杨3 分钟前
【AI编程系列】MCP 常用设计模式解读
设计模式·ai编程
wdfk_prog4 分钟前
lely-canopen-rtt:为什么推荐在 RT-Thread 上使用 Lely CANopen 构建主站
java·运维·缓存·docker·容器
海盗12348 分钟前
DSH 接入 OpenCode Go 报 400 MissingSessionID:从 LLM 语义层退到 fetch 传输层的完整排障
开发语言·后端·golang
Token掘金室10 分钟前
JSON模式结构化输出报错
java·服务器·json
秋饼15 分钟前
Spring AI 2.0 接入 DeepSeek V4.1 Flash 生产级实战
java·ai·技术分享·后端开发
IT枫斗者枫哥16 分钟前
Java 分批导出仍然 OOM?用 32 MiB 堆复现三种 CSV 写法
java
一木 之林17 分钟前
第 3 节 在 AI 行业中,C/C++ 编程中的动态库和静态库
c语言·c++·后端
skywalkerch23 分钟前
Spring 循环依赖与三级缓存
后端
shehuiyuelaiyuehao24 分钟前
算法43,外观数列,模拟算法+双指针
java·算法
萧瑟余晖44 分钟前
Hibernate 实体映射与关联关系详解
后端·hibernate