描述:
代理模式是一种结构型设计模式
,它为其他对象提供一种代理以控制对这个对象的访问。代理模式在不直接访问实际对象的情况下,提供了对目标对象的间接访问
。通过引入一个代理对象来间接操作实际对象,可以在不改变实际对象代码的前提下,增加额外的功能操作。
示例
// 定义主题接口
public interface ISubject
{
void Request();
}
// 实现主题接口的具体类
public class RealSubject : ISubject
{
public void Request()
{
Console.WriteLine("RealSubject:处理请求");
}
}
// 代理类,也实现主题接口
public class Proxy : ISubject
{
private RealSubject _realSubject;
public Proxy(RealSubject realSubject)
{
this._realSubject = realSubject;
}
public void Request()
{
if (this.CheckAccess())
{
this._realSubject.Request();
this.LogAccess();
}
}
private bool CheckAccess()
{
Console.WriteLine("Proxy: 在发出真正的请求之前检查访问权限。");
return true;
}
private void LogAccess()
{
Console.WriteLine("Proxy:记录请求的时间");
}
}
用处
• 访问控制:代理可以控制对真实对象的访问权限。
• 延迟初始化:代理可以在需要时才创建真实对象。
• 日志记录:代理可以在调用真实对象的方法前后添加日志记录。
• 性能优化:代理可以缓存结果,减少对真实对象的调用次数。
优点
• 增加灵活性:代理可以在不修改真实对象的情况下增加额外的功能。
• 保护目标对象:代理可以控制对目标对象的访问。
• 简化接口:代理可以简化复杂的接口。
缺点
• 增加复杂性:引入代理增加了系统的复杂性。
• 性能开销:代理可能会带来额外的性能开销。
案例1:远程代理
场景描述:客户端应用程序需要与远程服务器上的对象进行交互。为了简化网络通信,使用代理模式来处理网络请求。
代码示例
using System;
// 定义主题接口
public interface IRemoteService
{
string GetData();
}
// 远程服务的具体实现
public class RemoteService : IRemoteService
{
public string GetData()
{
// 模拟从远程服务器获取数据
return "来自远程服务器的数据";
}
}
// 远程代理
public class RemoteServiceProxy : IRemoteService
{
private RemoteService _remoteService;
public string GetData()
{
if (_remoteService == null)
{
_remoteService = new RemoteService();
}
Console.WriteLine("远程代理:正在获取数据...");
return _remoteService.GetData();
}
}
// 使用示例代码
public class Program
{
public static void Main()
{
IRemoteService remoteService = new RemoteServiceProxy();
string data = remoteService.GetData();
Console.WriteLine(data);
}
}
类图:
使用场景
• 分布式系统:客户端和服务器位于不同的物理位置,通过网络进行通信。
• 跨平台通信:客户端和服务器使用不同的编程语言或操作系统。
案例2:虚拟代理
场景描述:创建一个资源消耗较大的对象(如图像)时,使用代理模式来延迟对象的创建,直到真正需要时才创建。
代码示例
using System;
// 定义主题接口
public interface IImage
{
void Display();
}
// 大型图像的具体实现
public class LargeImage : IImage
{
private string _filename;
public LargeImage(string filename)
{
_filename = filename;
LoadFromDisk(_filename);
}
private void LoadFromDisk(string filename)
{
Console.WriteLine($"正在从磁盘加载 {_filename}");
}
public void Display()
{
Console.WriteLine($"正在显示 {_filename}");
}
}
// 虚拟代理
public class ImageProxy : IImage
{
private string _filename;
private LargeImage _image;
public ImageProxy(string filename)
{
_filename = filename;
}
public void Display()
{
if (_image == null)
{
Console.WriteLine("虚拟代理:图像尚未加载,现在开始加载...");
_image = new LargeImage(_filename);
}
_image.Display();
}
}
// 使用示例代码
public class Program
{
public static void Main()
{
IImage image = new ImageProxy("example.jpg");
// 图像尚未加载
image.Display();
// 图像已经加载
image.Display();
}
}
类图:
使用场景
• 大型文件加载:图像、视频等大型文件的加载。
• 数据库连接:延迟建立数据库连接,直到需要执行查询时才连接。
案例3:保护代理
场景描述:控制对敏感对象的访问权限,确保只有授权用户才能访问对象的方法。
代码示例
using System;
// 定义主题接口
public interface IBankAccount
{
void Deposit(int amount);
void Withdraw(int amount);
}
// 银行账户的具体实现
public class BankAccount : IBankAccount
{
private int _balance;
public void Deposit(int amount)
{
_balance += amount;
Console.WriteLine($"已存款 {amount},当前余额为 {_balance}");
}
public void Withdraw(int amount)
{
if (_balance >= amount)
{
_balance -= amount;
Console.WriteLine($"已取款 {amount},当前余额为 {_balance}");
}
else
{
Console.WriteLine("余额不足");
}
}
}
// 保护代理
public class BankAccountProxy : IBankAccount
{
private BankAccount _bankAccount;
private bool _isAdmin;
public BankAccountProxy(BankAccount bankAccount, bool isAdmin)
{
_bankAccount = bankAccount;
_isAdmin = isAdmin;
}
public void Deposit(int amount)
{
_bankAccount.Deposit(amount);
}
public void Withdraw(int amount)
{
if (_isAdmin)
{
_bankAccount.Withdraw(amount);
}
else
{
Console.WriteLine("访问被拒绝:只有管理员才能取款");
}
}
}
// 使用示例代码
public class Program
{
public static void Main()
{
IBankAccount bankAccount = new BankAccount();
IBankAccount adminProxy = new BankAccountProxy(bankAccount, isAdmin: true);
IBankAccount userProxy = new BankAccountProxy(bankAccount, isAdmin: false);
adminProxy.Deposit(1000);
adminProxy.Withdraw(500); // 管理员可以取款
userProxy.Deposit(200);
userProxy.Withdraw(100); // 普通用户无法取款
}
}
类图:
使用场景
• 权限控制:银行账户、文件系统等需要严格权限控制的系统。
• 安全访问:防止未授权用户访问敏感数据。