软件设计模式-代理模式

  • 代理模式
    • 意图:为其他对象提供一种代理以控制对这个对象的访问。
    • 例子:远程代理(访问远程对象)、虚拟代理(延迟加载大图片)、保护代理(控制权限)。
java 复制代码
// 1. 公共接口
interface Image {
    void display();
}

// 2. 真实对象(远程图片)
class RealImage implements Image {
    private String filename;
    
    public RealImage(String filename) {
        this.filename = filename;
        loadFromDisk(); // 模拟耗时的远程加载
    }
    
    private void loadFromDisk() {
        System.out.println("正在从远程服务器加载图片: " + filename);
        // 模拟网络延迟
        try { Thread.sleep(1000); } 
        catch (InterruptedException e) { e.printStackTrace(); }
    }
    
    @Override
    public void display() {
        System.out.println("显示图片: " + filename);
    }
}

// 3. 虚拟代理(延迟加载代理)
class ImageProxy implements Image {
    private String filename;
    private RealImage realImage;
    
    public ImageProxy(String filename) {
        this.filename = filename;
    }
    
    @Override
    public void display() {
        // 延迟初始化:第一次调用时才创建真实对象
        if (realImage == null) {
            realImage = new RealImage(filename);
        }
        realImage.display();
    }
}

// 4. 保护代理示例
interface SensitiveData {
    void access();
}

class RealData implements SensitiveData {
    private String data;
    
    public RealData(String data) {
        this.data = data;
    }
    
    @Override
    public void access() {
        System.out.println("访问敏感数据: " + data);
    }
}

class ProtectionProxy implements SensitiveData {
    private RealData realData;
    private String userRole;
    
    public ProtectionProxy(String data, String userRole) {
        this.realData = new RealData(data);
        this.userRole = userRole;
    }
    
    @Override
    public void access() {
        // 根据用户角色控制访问权限
        if ("admin".equals(userRole)) {
            realData.access();
        } else {
            System.out.println("拒绝访问:权限不足");
        }
    }
}

// 演示类
public class ProxyPatternDemo {
    public static void main(String[] args) {
        System.out.println("=== 虚拟代理演示(延迟加载)===");
        Image image1 = new ImageProxy("photo1.jpg");
        Image image2 = new ImageProxy("photo2.jpg");
        
        System.out.println("代理对象已创建,但真实图片未加载");
        System.out.println("首次调用display()时才会加载真实图片:");
        image1.display(); // 此时才加载真实图片
        
        System.out.println("\n=== 保护代理演示 ===");
        SensitiveData data1 = new ProtectionProxy("机密数据", "user");
        SensitiveData data2 = new ProtectionProxy("机密数据", "admin");
        
        data1.access(); // 普通用户被拒绝
        data2.access(); // 管理员可访问
        
        System.out.println("\n=== 远程代理演示 ===");
        Image remoteImage = new ImageProxy("remote_image.jpg");
        System.out.println("远程代理已创建");
        remoteImage.display(); // 模拟远程加载过程
    }
}

运行结果:

复制代码

复制代码
=== 虚拟代理演示(延迟加载)===
代理对象已创建,但真实图片未加载
首次调用display()时才会加载真实图片:
正在从远程服务器加载图片: photo1.jpg
显示图片: photo1.jpg

=== 保护代理演示 ===
拒绝访问:权限不足
访问敏感数据: 机密数据

=== 远程代理演示 ===
远程代理已创建
正在从远程服务器加载图片: remote_image.jpg
显示图片: remote_image.jpg

模式要点说明:

  1. 虚拟代理

    • 延迟创建开销大的对象(如大图片)
    • 第一次访问时才初始化真实对象
    • 优化性能,避免不必要的资源占用
  2. 远程代理

    • 隐藏远程对象的存在
    • 处理网络通信细节(示例中简化了网络操作)
    • 让客户端像使用本地对象一样使用远程对象
  3. 保护代理

    • 控制对敏感对象的访问
    • 在代理中添加权限检查逻辑
    • 真实对象无需关心权限验证

代理模式优势:

  • 职责分离:代理对象可以处理附加逻辑(如权限、缓存、日志)
  • 开闭原则:可以在不修改真实对象的情况下增加功能
  • 控制访问:提供更精细的对象访问控制

这个示例展示了代理模式在不同场景下的灵活应用,实际开发中还可以结合动态代理实现更通用的代理逻辑。

相关推荐
XX風6 分钟前
设计模式的本质
设计模式
折哥的程序人生 · 物流技术专研10 小时前
第8篇:六大设计原则在工厂模式中的体现
java·设计模式·设计原则·工厂模式·编程进阶·扩充系列
咖啡八杯11 小时前
GoF设计模式——模板方法模式
java·后端·spring·设计模式
饼干哥哥21 小时前
Openclaw已死?任何Agent都能用Cli实现AI自主运营跨境电商
设计模式·openai·ai编程
折哥的程序人生 · 物流技术专研1 天前
第4篇:抽象工厂模式——产品族一键创建
java·设计模式·抽象工厂模式·创建型模式·编程进阶·产品族·扩充系列
geovindu1 天前
go: Cascading Failures Pattern
开发语言·后端·设计模式·golang·反模式·级联失效反模式
端庄的战斗机2 天前
javascript 设计模式(文章很长,请自备瓜子,水果和眼药水)
开发语言·javascript·设计模式
饼干哥哥2 天前
我开发了一个「吃掉」别人Skill来升级的饕餮.Skill,现在免费开源
人工智能·设计模式·开源
CaffeinePro2 天前
什么是系统架构?架构师到底在做什么?
设计模式·架构