一、简介
代理模式
是一种结构型设计模式,它允许通过创建一个代理对象来控制对另一个对象的访问
代理对象充当了客户端和被代理对象之间的中介,客户端通过代理对象来访问被代理对象,从而实现了对被代理对象的间接访问。
二、功能
代理模式的主要目的:在不改变原始对象的情况下,提供额外的功能或控制访问。
它可以用于实现以下几种情况:
1.🎈 远程代理: 当对象位于不同的地址空间时,可以使用代理模式来实现远程访问。代理对象充当了客户端和远程对象之间的代理,隐藏了底层的网络通信细节。
2. 🎈虚拟代理: 当创建一个对象的开销很大时,可以使用代理模式来延迟对象的实例化。代理对象在需要时才会实例化真正的对象,并在后续访问中重复使用。
3. 🎈安全代理: 代理模式还可以用于控制对对象的访问权限。代理对象可以检查客户端的访问权限,并决定是否允许访问真正的对象。
4. 🎈缓存代理: 代理模式还可以用于实现结果的缓存。代理对象可以缓存对真正对象的调用结果,并在后续相同的调用中直接返回缓存的结果,从而提高性能。
代理模式的实现通常涉及两个角色:
1. 👀抽象接口: 定义了代理对象和真正对象之间的公共接口,客户端通过这个接口来访问真正的对象。
2. 👀真正对象: 实现了抽象接口,是被代理的对象。客户端通过代理对象间接访问真正对象。
三、代理模式的好处
代理模式有以下几个好处和作用:
1. 代理对象可以充当真正对象的访问控制器,可以控制对真正对象的访问权限。 代理对象可以在访问真正对象之前进行权限检查,从而提供更加安全的访问控制。
2. 代理对象可以在访问真正对象之前或之后添加额外的逻辑。这样可以实现一些横切关注点(cross-cutting concerns),如日志记录、性能监控、缓存等,而无需修改真正对象的代码。
3. 代理模式可以实现延迟加载(lazy loading)。 代理对象可以在需要的时候才创建真正对象,从而提高系统的性能和资源利用率。
4. 代理模式可以隐藏真正对象的实现细节,对客户端透明。客户端只需要通过代理对象来访问真正对象,无需关心真正对象的具体实现。
5. 代理模式可以实现远程代理。 代理对象可以作为真正对象在不同进程或不同服务器上的代表,客户端可以通过代理对象来访问远程的真正对象。
总的来说,代理模式可以提供更加灵活、安全、高效和可维护的访问方式,同时也可以实现一些与业务逻辑无关的横切关注点。它在软件开发中被广泛应用,特别是在需要对访问进行控制和管理的场景中。
四、python代码实例
以下是一个简单的Python示例代码,演示了代理模式的基本结构:
# 抽象接口
class Subject:
def request(self):
pass
# 真正对象
class RealSubject(Subject):
def request(self):
print("真正对象的请求")
# 代理对象
class Proxy(Subject):
def __init__(self, real_subject):
self.real_subject = real_subject
def request(self):
# 在访问真正对象之前可以添加额外的逻辑
print("代理对象的请求")
self.real_subject.request()
# 在访问真正对象之后可以添加额外的逻辑
# 客户端
real_subject = RealSubject()
proxy = Proxy(real_subject)
proxy.request()
在这个示例中,抽象接口Subject
定义了代理对象和真正对象之间的公共接口。真正对象RealSubject
实现了抽象接口,并定义了真正的请求逻辑。代理对象Proxy
也实现了抽象接口,并在其request
方法中调用真正对象的request
方法。客户端通过创建真正对象和代理对象来使用代理模式。客户端通过代理对象来访问真正对象,代理对象可以在访问真正对象前后添加额外的逻辑。
五、C++代码实例
当然,下面是一个使用C++实现代理模式的简单示例:
#include <iostream>
// 抽象接口
class Subject {
public:
virtual void request() = 0;
};
// 真正对象
class RealSubject : public Subject {
public:
void request() override {
std::cout << "真正对象的请求" << std::endl;
}
};
// 代理对象
class Proxy : public Subject {
private:
Subject* realSubject;
public:
Proxy(Subject* realSubject) : realSubject(realSubject) {}
void request() override {
// 在访问真正对象之前可以添加额外的逻辑
std::cout << "代理对象的请求" << std::endl;
realSubject->request();
// 在访问真正对象之后可以添加额外的逻辑
}
};
// 客户端
int main() {
Subject* realSubject = new RealSubject();
Subject* proxy = new Proxy(realSubject);
proxy->request();
delete realSubject;
delete proxy;
return 0;
}
在这个示例中,我们使用C++
语言实现了代理模式。抽象接口Subject
定义了代理对象和真正对象之间的公共接口,真正对象RealSubject
继承自抽象接口,并实现了真正的请求逻辑。代理对象Proxy
也继承自抽象接口,并在其request
方法中调用真正对象的request
方法。
在客户端的main
函数中,我们创建了真正对象和代理对象,并通过代理对象来访问真正对象。代理对象可以在访问真正对象前后添加额外的逻辑。
注意⚠️: 为了避免内存泄漏,我们在客户端的main
函数中使用new
关键字创建了真正对象和代理对象,然后在程序结束前使用delete
关键字释放了它们的内存。