代理模式(Proxy Pattern)为对象提供一个代理进而控制对其的访问。

例如我们需要加载一张图片,但加载图片是个访问网络或 IO 的操作,我们不希望这个这个操作阻塞 UI 线程,于是我们可以定义一个代理来进行多线程的加载,并在加载完成后显示图片。

#代码示例

#抽象接口

图片接口
1
2
3
4
public interface Icon
{
void PrintIconWidthAndHeight();
}

#抽象接口实现

真实图片类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ImageIcon : Icon
{
private int width, height;
public ImageIcon()
{
Thread.Sleep(5000);//Pretend there is some hard work to load the image
width = 800;
height = 1000;
}
public void PrintIconWidthAndHeight()
{
Console.WriteLine(DateTime.Now.ToLongTimeString() + ": Width is " + width + ",height is " + height);
}
}
代理图片类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ImageProxyIcon : Icon
{
private ImageIcon icon = null;
private bool isLoading = false;

public ImageProxyIcon() { }

public void PrintIconWidthAndHeight()
{
if (icon != null)
icon.PrintIconWidthAndHeight();
else if (!isLoading)
{
Console.WriteLine(DateTime.Now.ToLongTimeString() + ": Is Loading Image...");
isLoading = true;
new Thread(() =>
{
icon = new ImageIcon();
icon.PrintIconWidthAndHeight();
}).Start();
}
}
}

#测试代码及结果

测试代码
1
2
ImageProxyIcon proxyIcon = new ImageProxyIcon();
proxyIcon.PrintIconWidthAndHeight();

运行结果:

代理模式运行结果

代理模式与装饰模式很像,不同的是装饰模式的目的是在原先的类外扩展某些功能,而代理模式只是控制原先类中某些接口的访问。例如上例子中,ImageProxyIcon并没有为ImageIcon拓展什么功能,只是用了多线程来访问访问其中的函数。