模式定义
代理模式(Proxy Pattern) :给某一个对象提供一个代理,并由代理对象控制对原对象的引用。
代理模式实现方式就算添加一个代理类,代理类对被代理类进行包装以实现应用场景。
UML类图
- 抽象主题角色 Subject 真实主题和代理主题的共同接口
- 代理主题角色 Proxy 依赖真实主题角色,从而可以在任何时候操作真实主题对象
- 真实主题角色 RealSubject 代理角色所代表的真实对象,在真实主题角色中实现了真实的业务操作
代码结构
public static class ProxyApp
{
public static void Run()
{
Subject subject = new Proxy();
subject.Request();
}
}
public abstract class Subject
{
public abstract void Request();
}
public class RealSubject : Subject
{
public override void Request()
{
Console.WriteLine("Called RealSubject.Request()");
}
}
public class Proxy : Subject
{
private RealSubject _realSubject;
public override void Request()
{
if(_realSubject == null)
{
_realSubject = new RealSubject();
}
_realSubject.Request();
}
}
情景实例
在开发过程中难免遇到调用WebService,我们可以直接发送请求调用,但是这样一个函数发送一个请求未免太麻烦。可以在客户端创建一WebService
代理类,这样客户端就可以像调用本地类一样方便。这种叫做远程代理,实现控制台为Client,调用WebService。
- 服务端创建:新建空的WebForm网站,添加MathService.amsx文件,代码如下。
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class MathService : System.Web.Services.WebService
{
[WebMethod]
public int Add(int a,int b)
{
return (a + b);
}
[WebMethod]
public int Substract(int a, int b)
{
return (a - b);
}
[WebMethod]
public int Multiplly(int a,int b)
{
return a * b;
}
[WebMethod]
public int Divide(int a,int b)
{
return (a / b);
}
}
- 新建客户端控制台Client。通过
wsdl
生成调用服务类
打开VisualStudio Command Prompt.输入wsdl /out:E:\\MathService.cs http://localhost:25047/WebService/MathService.asmx
(主要切换成自己的WebService的Url)。
新建代理类MathProxy
public class MathProxy
{
private MathService _mathService = new MathService();
public MathProxy(string url)
{
_mathService.Url = url;
}
public int Add(int a, int b)
{
return _mathService.Add(a,b);
}
public int Substract(int a, int b)
{
return _mathService.Substract(a,b);
}
public int Multiplly(int a, int b)
{
return _mathService.Multiplly(a,b);
}
public int Divide(int a, int b)
{
return _mathService.Divide(a,b);
}
}
调用测试
static void Main(string[] args)
{
string url = "http://localhost:25047/WebService/MathService.asmx";
MathProxy math = new MathProxy(url);
Console.WriteLine("Method Add:2+3");
Console.WriteLine(math.Add(2, 3));
Console.WriteLine("Method Substract:5-3");
Console.WriteLine(math.Substract(5, 3));
Console.WriteLine("Method Multiplly:4*7");
Console.WriteLine(math.Multiplly(4, 7));
Console.WriteLine("Method Divide:8/4");
Console.WriteLine(math.Divide(8, 4));
Console.ReadKey();
}
扩展
代理的应用很广泛,根据使用的目的可分为:
- 远程代理(上面演示的例子)
- 虚拟代理
- 保护代理
- 缓冲代理