【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 小时前
Agent 工具调用:从工具声明到执行反馈
前端·人工智能·后端
别动我齐刘海4 小时前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
码事漫谈4 小时前
你让AI干的活,它可能只干了十分之一——而你根本看不出来
后端
Wx-bishekaifayuan4 小时前
express皖美特色农产品网售系统53118-计算机课程设计、毕业设计
人工智能·spring boot·后端·python·课程设计·express·旅游
Wx-bishekaifayuan5 小时前
springboot汉中旅游服务平台41442-计算机课程设计、毕业设计
spring boot·后端·python·django·课程设计·express·旅游
code2cat5 小时前
Java进阶篇之AtomicLongFieldUpdater:把累计额度留在对象字段中
java·cas·并发编程
WeiXin_DZbishe5 小时前
基于springboot城市公交实时运营与调度系统-计算机毕设 附源码【课程设计】66173
java·vue.js·spring boot·后端·python·php·课程设计
泡茶喝茶写代码5 小时前
A股量化数据工程:从 REST 接口到策略信号(第 18 篇):放量缩量异动扫描
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
WeiXin_DZbishe5 小时前
基于Springboot+AI的kuall音乐广场的设计与实现-计算机毕设 附源码【课程设计】12715
vue.js·人工智能·spring boot·后端·python·php·课程设计