设计模式<结构型> | 代理模式

代理模式(Proxy Pattern)

在不改变原始类(或叫被代理类)的情况下,通过引入代理类来给原始类附加功能。一般情况下,让代理类和原始类实现同样的接口。但是,如果原始类并没有定义接口,并且原始类代码并不是自己开发维护的。在这种情况下,可以通过让代理类继承原始类的方法来实现代理模式。

结构图:

角色:

  1. 原始主题(RealSubject):也就是需要被代理的类。
  2. 抽象主题(ISubject):真实主题和代理主题的公共接口。
  3. 代理主题角色(Proxy):代理类,用于在被代理类执行前后执行其他方法。

适用场景:

  1. 非功能性需求,譬如。监控、统计、鉴权、限流、事务、幂等、日志。将这些附加功能与业务功能解耦,放到代理类统一处理。

优点:

  1. 可以不修改原始类的前提下给其增加一些额外的功能。
  2. 可以在不对服务或客户端做出修改的情况下创建新代理。

缺点

  1. 需要增加代理类,提高了代码复杂度。

代码(C#)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

/// <summary>
/// 通用接口
/// </summary>
public interface ISubject
{
void Request();
}

/// <summary>
/// 需要被代理的类
/// </summary>
public class RealSubject : ISubject
{
public void Request()
{
Console.WriteLine("被代理类的原始逻辑");
}
}

/// <summary>
/// 代理
/// </summary>
public class Proxy : ISubject
{
private ISubject _realSubject;

public Proxy(ISubject realSubject)
{
_realSubject = realSubject;
}

public void Request()
{
Check();
// 代理原始主题执行
_realSubject.Request();
}

public void Check()
{
Console.WriteLine("检查参数");
}
}

ISubject realSubject = new Proxy(new RealSubject());

realSubject.Request();

最后

这种通过穿件代理的方式是静态代理,静态代理需要针对每个类都创建一个代理类,并且每个代理类中的代码都有点像模板式的重复代码,加了维护成本和开发成本。对于静态代理存在的问题,可以通过动态代理来解决。不事先为每个原始类编写代理类,而是在运行的时候动态地创建原始类对应的代理类,然后在系统中用代理类替换掉原始类。


设计模式<结构型> | 代理模式
http://example.com/posts/51465.html
作者
她微笑的脸y
发布于
2023年2月28日
许可协议