98、23种设计模式之代理模式(7/23)
代理模式 (Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。
一、代理模式的形式
1.远程代理:为远程对象提供本地代表
2.虚拟代理:根据需要创建开销很大的对象
3.保护代理:控制对原始对象的访问权限
4.智能引用代理:在访问对象时执行附加操作
二、基本实现示例
1. 接口定义
// 主题接口
public interface ISubject
{void Request();
}
2. 真实主题类
// 真实主题类
public class RealSubject : ISubject
{public void Request(){Console.WriteLine("RealSubject: 处理请求");}
}
3. 代理类
// 代理类
public class Proxy : ISubject
{private RealSubject _realSubject;public void Request(){// 在调用真实对象方法前后可以添加额外逻辑if (_realSubject ==){_realSubject = new RealSubject();}Console.WriteLine("Proxy: 在调用真实对象前");_realSubject.Request();Console.WriteLine("Proxy: 在调用真实对象后");}
}
4. 客户端使用
class Program
{static void Main(string[] args){Proxy proxy = new Proxy();proxy.Request();}
}
三、实际应用示例
1、虚拟代理示例 - 图片加载代理
// 图片接口
public interface IImage
{void Display();
}// 真实图片类(加载可能很耗时)
public class RealImage : IImage
{private string _filename;public RealImage(string filename){_filename = filename;LoadFromDisk();}private void LoadFromDisk(){Console.WriteLine($"加载图片: {_filename}");// 模拟耗时操作Thread.Sleep(2000);}public void Display(){Console.WriteLine($"显示图片: {_filename}");}
}// 图片代理(虚拟代理)
public class ImageProxy : IImage
{private string _filename;private RealImage _realImage;public ImageProxy(string filename){_filename = filename;}public void Display(){if (_realImage ==){_realImage = new RealImage(_filename);}_realImage.Display();}
}// 使用
class Program
{static void Main(){IImage image = new ImageProxy("test.jpg");// 第一次调用会实际加载图片Console.WriteLine("第一次调用:");image.Display();// 第二次调用直接使用已加载的图片Console.WriteLine("\n第二次调用:");image.Display();}
}
2.保护代理示例 - 权限控制
// 文档接口
public interface IDocument
{void Display();void Edit();
}// 真实文档
public class RealDocument : IDocument
{private string _content;public RealDocument(string content){_content = content;}public void Display(){Console.WriteLine($"显示文档内容: {_content}");}public void Edit(){Console.WriteLine("编辑文档...");}
}// 文档代理(保护代理)
public class DocumentProxy : IDocument
{private RealDocument _document;private string _userRole;public DocumentProxy(string content, string userRole){_document = new RealDocument(content);_userRole = userRole;}public void Display(){_document.Display();}public void Edit(){if (_userRole == "Admin"){_document.Edit();}else{Console.WriteLine("无权限编辑文档");}}
}// 使用
class Program
{static void Main(){IDocument adminDoc = new DocumentProxy("机密文件", "Admin");IDocument userDoc = new DocumentProxy("普通文件", "User");Console.WriteLine("管理员尝试:");adminDoc.Display();adminDoc.Edit();Console.WriteLine("\n普通用户尝试:");userDoc.Display();userDoc.Edit();}
}
四、.NET 中的代理模式应用
- WCF 服务代理:自动生成的客户端代理类
- EF Core 延迟加载:通过代理实现延迟加载
- 装饰器模式:常与代理模式结合使用
- AOP 框架:如 Castle DynamicProxy
代理模式在需要控制资源访问、延迟加载或添加额外行为时非常有用,同时保持客户端代码的简洁性。