[5] [接口隔离] ( 2 ) 代理模式 proxy
总结
-
什么情况下用代理模式?
出于某种原因(创建对象开销/安全控制/跨进程访问...),
直接访问会造成很多麻烦,
这时需要增加间接层,使用代理模式.
-
GOF定义
为其他对象提供一种代理以控制(隔离, 使用接口)对这个对象的访问.
(重点是控制该对象的访问)
-
具体做法?
创建一个类, 让这个类充当其他事物的接口.
-
实际场景情况?
proxy并不一定要求保持接口完整的一致性,
只要能够实现简介控制,
有时候损失一些透明性是可以接受的.
-
代理类型?
虚拟代理
缓存代理
保护代理
远程代理
智能应用代理
-
应用场景?
缓存
访问控制
延迟实例化
远程访问
额外的行为

java例子1
缓存代理/虚拟代理
.
这个例子中,
使用代理模式,
可以起到缓存效果,
优化计算资源.
package v21_proxy.java;
// 图片爬虫类
class RemoteImage {
private String url; // 图片url来源
public RemoteImage(String url) {
this.url = url;
}
// 负责加载展示图片
public void displayImage() {
// 模拟加载和展示...
System.out.println("Displaying image from URL: " + url);
// Code to load and display the image
}
}
// 代理类
public class ImageProxy {
private String url;
private RemoteImage image; // 图片爬虫对象
public ImageProxy(String url) {
this.url = url;
this.image = null;
}
public void displayImage() {
// 起到缓存效果.
if (image == null) {
System.out.println("New image from URL: " + url);
image = new RemoteImage(url);
}
image.displayImage();
}
public static void main(String[] args) {
ImageProxy imageProxy = new ImageProxy("http://example.com/image.jpg");
imageProxy.displayImage(); // Image is loaded from the server
imageProxy.displayImage(); // Image is loaded from the cache
}
}
java例子2
保护代理
package v21_proxy.java;
// 银行账户
interface BankAccount {
void deposit(double amount); // 存款
void withdraw(double amount); // 提款
}
// 真实账户对象
class RealBankAccount implements BankAccount {
private double balance;
public RealBankAccount(double initialBalance) {
this.balance = initialBalance;
}
@Override
public void deposit(double amount) {
balance += amount;
System.out.println("Deposited: " + amount + ", new balance: " + balance);
}
@Override
public void withdraw(double amount) {
if (balance >= amount) {
balance -= amount;
System.out.println("Withdrew: " + amount + ", new balance: " + balance);
} else {
System.out.println("Insufficient balance");
}
}
}
// 代理账户对象
class BankAccountProxy implements BankAccount {
private RealBankAccount realBankAccount;
private String userRole;
public BankAccountProxy(String userRole, double initialBalance) {
this.userRole = userRole;
this.realBankAccount = new RealBankAccount(initialBalance);
}
@Override
public void deposit(double amount) {
// 存款没有限制
if (userRole.equals("Admin") || userRole.equals("User")) {
realBankAccount.deposit(amount);
} else {
System.out.println("Unauthorized access");
}
}
@Override
public void withdraw(double amount) {
// 限制admin以外的权限进行取款, 非Admin, 不能调用RealBankAccount取款.
if (userRole.equals("Admin")) {
realBankAccount.withdraw(amount);
} else {
System.out.println("Unauthorized access");
}
}
}
public class BankAccountProxyMain {
public static void main(String[] args) {
BankAccount adminAccount = new BankAccountProxy("Admin", 1000);
adminAccount.deposit(500);
adminAccount.withdraw(200);
BankAccount userAccount = new BankAccountProxy("User", 1000);
userAccount.deposit(500);
userAccount.withdraw(200); // Will print "Unauthorized access"
}
}
c++例子
class ISubject{
public:
virtual void process();
};
class RealSubject: public ISubject{
public:
virtual void process(){ /* ... */ }
};
class SubjectProxy: public ISubject{
public:
virtual void process(){
/* 对RealSubject的一种间接访问 */
}
};
// 直接用RealSubject
class ClientApp{
ISubject* subject;
public:
ClientApp(){
subject=new RealSubject();
}
void DoTask(){
subject->process();
//....
}
};
// 使用代理模式
class ClientApp{
ISubject* subject;
public:
ClientApp(){
subject=new SubjectProxy();
}
void DoTask(){
subject->process();
}
};
浙公网安备 33010602011771号