设计模式(012)结构型之代理模式

代理模式通过创建代理对象控制对原对象的访问,支持延迟加载,例如在显示图片时只有在真正需要时才加载。文中给出了C++和Java两种语言实现的Image接口及RealImage和ProxyImage类,展示如何利用代理模式进行延迟加载以提高性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        代理模式是通过创建一个代理对象,来控制对另一个对象的访问。代理对象和被代理对象实现了相同的接口,因此对客户端而言,它们是可以互换的。客户端通过调用代理对象的方法来访问被代理对象,代理对象可以在调用被代理对象之前或之后执行一些额外的操作,比如记录日志、实现缓存等。
        代理模式通常用于以下场景:
远程代理:客户端通过代理对象访问远程的对象,代理对象将请求发送到远程对象,并将结果返回给客户端。
虚拟代理:在客户端访问一个复杂对象时,代理对象可以先返回一个占位符,等到真正需要使用时再创建真实的对象,以节省资源。
安全代理:代理对象可以控制客户端对被代理对象的访问,比如限制访问权限。        

1、场景设计

实现场景:Image 接口定义了 display() 方法,RealImage 类实现了 Image 接口,并在其构造函数中加载了指定的文件。ProxyImage 类也实现了 Image 接口,并在其 display() 方法中判断实际的 RealImage 对象是否已经创建。如果没有创建,则创建一个新的 RealImage 对象,并调用其 display() 方法;如果已经创建,则直接调用 RealImage 对象的 display() 方法。通过使用代理模式,在实际对象创建之前对其进行延迟加载,从而提高应用程序的性能。

2、C++实现

#include <iostream>
#include <string>

using namespace std;

// Subject 接口
class Image {
    public:
        virtual void display() = 0;
};

// RealSubject 类
class RealImage : public Image {
    public:
        RealImage(std::string file_name) : m_file_name(file_name) {loadFromDisk(file_name);}

        void display() override {
            std::cout << "Displaying " << m_file_name << std::endl;
        }

        void loadFromDisk(std::string file_name){
            std::cout << "Loading " << file_name << std::endl;
        }

    private:
        std::string m_file_name;
};

// Proxy 类
class ProxyImage : public Image {

    public:
        ProxyImage(std::string file_name) : m_file_name(file_name) {}

    void display() override {
        if(real_image_ == NULL){
            real_image_ = new RealImage(m_file_name);
        }
        real_image_->display();
    }

    private:
        RealImage* real_image_ = NULL;
        std::string m_file_name;
};

int main() {
    Image* image = new ProxyImage("test.jpg");
    // 第一次访问,实际的 Image 对象还没有创建
    image->display();
    // 第二次访问,实际的 Image 对象已经创建了,因此不会再次加载
    image->display();
    delete image;
    return 0;
}

 3、Java实现

package structuralpattern.proxy;

// Subject 接口
interface Image {
    void display();
}

// RealSubject 类
class RealImage implements Image {
    private String fileName;

    public RealImage(String fileName) {
        this.fileName = fileName;
        loadFromDisk(fileName);
    }

    @Override
    public void display() {
        System.out.println("Displaying " + fileName);
    }

    private void loadFromDisk(String fileName) {
        System.out.println("Loading " + fileName);
    }
}

// Proxy 类
class ProxyImage implements Image {
    private RealImage realImage;
    private String fileName;

    public ProxyImage(String fileName) {
        this.fileName = fileName;
    }

    @Override
    public void display() {
        if (realImage == null) {
            realImage = new RealImage(fileName);
        }
        realImage.display();
    }
}

public class ProxyDemo {
    public static void main(String[] args) {
        Image image = new ProxyImage("test.jpg");
        // 第一次访问,实际的 Image 对象还没有创建
        image.display();
        // 第二次访问,实际的 Image 对象已经创建了,因此不会再次加载
        image.display();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值