通过引入一个代理对象(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 通过代理模式,我们可以在下载资源前进行权限检查和记录下载日志,而无需修改真实主题类的代码。这样,代理模式为我们提供了一种方便的方式来添加额外功能或控制,同时保持原始对象的功能不受影响。