通过引入一个代理对象(Proxy)来对实际的业务对象附加一定的逻辑——也就是说要不要调用真正的业务逻辑对象方法,由代理决定。
举个例子:CDN缓存其实就是一个代理——如果CDN网络中没有要访问的资源,那么回原站,如果有的话,就直接返回了。
看个例子吧。
1 假设我们有一个网络资源下载器,我们想要在下载资源前检查用户是否有权限进行下载,以及记录下载日志。为了实现这些功能,我们可以使用代理模式。 2 3 首先,我们定义一个抽象主题接口 IDownloader: 4 5 6 public interface IDownloader 7 { 8 void Download(string url); 9 } 10 11 然后,我们实现真实主题类 RealDownloader,用于执行资源的下载: 12 13 public class RealDownloader : IDownloader 14 { 15 public void Download(string url) 16 { 17 Console.WriteLine($"Downloading resource from {url}"); 18 } 19 } 20 21 接下来,我们实现代理类 ProxyDownloader,在下载资源之前进行权限检查和日志记录: 22 23 public class ProxyDownloader : IDownloader 24 { 25 private RealDownloader realDownloader = new RealDownloader(); 26 27 public void Download(string url) 28 { 29 // 权限检查 30 if (CheckPermission()) 31 { 32 // 记录日志 33 LogDownload(url); 34 // 执行下载 35 realDownloader.Download(url); 36 } 37 else 38 { 39 Console.WriteLine("Permission denied. Cannot download resource."); 40 } 41 } 42 43 private bool CheckPermission() 44 { 45 // 这里模拟权限检查,假设用户有权限下载资源 46 return true; 47 } 48 49 private void LogDownload(string url) 50 { 51 Console.WriteLine($"Downloading resource from {url} - {DateTime.Now}"); 52 } 53 } 54 55 56 现在,我们可以使用代理模式来下载资源: 57 58 class Program 59 { 60 static void Main(string[] args) 61 { 62 IDownloader downloader = new ProxyDownloader(); 63 downloader.Download("https://www.example.com/resource.txt"); 64 } 65 } 66 67 通过代理模式,我们可以在下载资源前进行权限检查和记录下载日志,而无需修改真实主题类的代码。这样,代理模式为我们提供了一种方便的方式来添加额外功能或控制,同时保持原始对象的功能不受影响。