代理模式是一种结构型设计模式,它为其他对象提供一种代理(或占位符)以控制对该对象的访问。通过代理模式,我们可以在不修改目标对象的情况下,控制对其的访问,添加额外的功能,比如懒加载、权限检查、日志记录等。
代理模式主要通过为目标对象创建一个代理对象来代替真实对象,代理对象可以控制对目标对象的访问,并可以在访问时提供附加功能。
代理模式通常包括以下角色:
假设我们有一个银行账户类,用户可以通过该类来进行资金的存取操作。为了安全起见,银行希望对这些操作进行日志记录和权限控制。因此,我们可以使用代理模式来实现:
首先定义一个接口,表示银行账户的基本操作。
// 主题接口
public interface BankAccount {
void deposit(double amount);
void withdraw(double amount);
double getBalance();
}
真实对象实现了 BankAccount
接口,并提供具体的业务操作。
// 真实对象
public 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 (amount <= balance) {
balance -= amount;
System.out.println("Withdrew " + amount + ", New balance: " + balance);
} else {
System.out.println("Insufficient funds!");
}
}
@Override
public double getBalance() {
return balance;
}
}
代理对象实现了 BankAccount
接口,并在方法调用时添加额外的功能(如权限控制和日志记录)。
// 代理对象
public class BankAccountProxy implements BankAccount {
private RealBankAccount realBankAccount;
public BankAccountProxy(double initialBalance) {
realBankAccount = new RealBankAccount(initialBalance);
}
@Override
public void deposit(double amount) {
logAction("deposit", amount);
realBankAccount.deposit(amount);
}
@Override
public void withdraw(double amount) {
logAction("withdraw", amount);
realBankAccount.withdraw(amount);
}
@Override
public double getBalance() {
return realBankAccount.getBalance();
}
private void logAction(String action, double amount) {
System.out.println("Logging: Action = " + action + ", Amount = " + amount);
}
}
客户端通过代理对象来进行存款和取款操作,而不需要直接与真实对象交互。
public class Client {
public static void main(String[] args) {
BankAccount account = new BankAccountProxy(1000);
// 客户端通过代理对象进行操作
account.deposit(500);
account.withdraw(200);
account.withdraw(1000);
System.out.println("Final balance: " + account.getBalance());
}
}
Logging: Action = deposit, Amount = 500.0
Deposited 500.0, New balance: 1500.0
Logging: Action = withdraw, Amount = 200.0
Withdrew 200.0, New balance: 1300.0
Logging: Action = withdraw, Amount = 1000.0
Withdrew 1000.0, New balance: 300.0
Final balance: 300.0
在这个例子中,代理对象 BankAccountProxy
在调用真实银行账户的操作之前进行了日志记录,增加了访问控制的功能,而客户端并不需要知道这些细节。
设计模式 | 主要用途 | 与代理模式的区别 |
---|---|---|
装饰模式 | 动态地给对象添加额外的功能。 | 装饰模式通常是给对象添加行为,而代理模式是控制对对象的访问。 |
适配器模式 | 将接口转化为客户端期望的接口,使得两个不兼容的接口可以协同工作。 | 适配器模式用于接口适配,而代理模式用于控制访问。 |
单例模式 | 确保类只有一个实例并提供全局访问点。 | 单例模式通常是限制实例数量,而代理模式是控制对对象的访问。 |
代理模式是一种非常实用的设计模式,它通过引入代理对象来控制对真实对象的访问,从而为客户端提供附加的功能,比如权限控制、延迟加载、日志记录等。代理模式可以透明地为客户端提供真实对象的功能,同时避免客户端直接依赖目标对象,从而使得系统更具灵活性和可扩展性。
在实际应用中,代理模式可以应用于许多场景,如远程代理、虚拟代理、保护代理和智能代理等。通过使用代理模式,能够在不改变目标对象的情况下,为目标对象添加额外的功能,同时有效地控制对象的访问。