软件设计模式-代理模式

  • 代理模式
    • 意图:为其他对象提供一种代理以控制对这个对象的访问。
    • 例子:远程代理(访问远程对象)、虚拟代理(延迟加载大图片)、保护代理(控制权限)。
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. 保护代理

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

代理模式优势:

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

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

相关推荐
雨中飘荡的记忆17 小时前
工厂模式详解
设计模式
Charles_go19 小时前
C#42、什么是建造者设计模式
设计模式
烤麻辣烫21 小时前
23种设计模式(新手)-3接口隔离原则
java·开发语言·学习·设计模式·intellij-idea
e***U8201 天前
算法设计模式
算法·设计模式
颜酱1 天前
理解编程的设计模式(前端角度)
设计模式
ZHE|张恒1 天前
设计模式(五)原型模式 — 通过克隆快速复制对象,避免复杂初始化
设计模式·原型模式
敖云岚2 天前
【设计模式】简单易懂的行为型设计模式-策略模式
设计模式·策略模式
IT永勇2 天前
C++设计模式-单例
c++·单例模式·设计模式
ZHE|张恒2 天前
设计模式(四)建造者模式 — 分步骤构建复杂对象,让创建过程可控可扩展
设计模式·建造者模式