【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中就是基于代理模式来做到方法的增强,但使用的是动态代理技术。代理模式本身属于静态代理技术,动态代理是静态代理的升级。

相关推荐
踩着两条虫10 小时前
「AI + 低代码」的可视化设计器
开发语言·前端·低代码·设计模式·架构
budingxiaomoli11 小时前
Spring IoC &DI
java·spring·ioc·di
Spider Cat 蜘蛛猫11 小时前
Springboot SSO系统设计文档
java·spring boot·后端
未若君雅裁11 小时前
MySQL高可用与扩展-主从复制读写分离分库分表
java·数据库·mysql
学习中.........11 小时前
从扰动函数的变化,感受红黑树带来的性能提升
java
计算机安禾12 小时前
【c++面向对象编程】第24篇:类型转换运算符:自定义隐式转换与explicit
java·c++·算法
zyk_computer12 小时前
AI 时代,或许 Rust 比 Python 更合适
人工智能·后端·python·ai·rust·ai编程·vibe coding
weixin1997010801612 小时前
【保姆级教程】淘宝/天猫商品详情 API(item_get)接入指南:Python/Java/PHP 调用示例与 JSON 返回值解析
java·python·php
环流_12 小时前
redis核心数据类型在java中的操作
java·数据库·redis
雨辰AI12 小时前
SpringBoot3 项目国产化改造完整流程|从 MySQL 到人大金仓落地
java·数据库·后端·mysql·政务