设计模式--Proxy代理模式
一、何为代理
顾名思意,所谓代理模式就是通过增加一个中间层(代理类)来操控我们实际要操控的另一个对象,就像一个歌星或专业运动员的经纪人一样,被操控的对象或者是 因为很复杂,或者是因为需要较长的时间才能进行构造,也或者是因为分布在网络的其它位置,这些都需要我们通过代理来解决如何使用这些对象的问题。
二、 我们的例子
比如在网络异地,有一个专门的服务器用于提供专业的天气预报的相关信息,我们在网络的其它地方需要获取我们感兴趣的城市的天气预报,为此,我们需要在客户 端本地创建一个代理类,由它来与异地的天气预报服务器上的相关服务进行交互,并按照定制的接口对本地开放,我们通过这些接口所开放的服务来获取我们想要的 相关信息。下面就是我们的实现。
1、定义接口IWeather.它的作用:当我们在代理类WeatherProxy中调用了原实现类Weather的方法时,Weather类并不一定实 现了所有的方法,为了强迫Weather类实现所有的方法,同时也为了我们更加透明的去操作对象,我们在Weather类和WeatherProxy类的 基础上加上一层抽象,即它们都实现与IWeather接口
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ProxyPatternWeather
{
//定义一个接口
//Weather类和WeatherProxy类都需要实现与IMath接口
public interface IWeather
{
string GetTemperature(string city);
string GetWind(string city);
string GetAirQuality(string city);
}
}
2、定义原实现类Weather
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ProxyPatternWeather
{
public class Weather:IWeather
{
//根据传参,在服务器数据库中获取相应数据并返回结果
//在Weather类中需要实现IWeather接口
public string GetTemperature(string city)
{
//数据库操作
return city + "的温度为23摄氏度";
}
public string GetWind(string city)
{
//数据库操作
return city + "风向东南二级";
}
public string GetAirQuality(string city)
{
//数据库操作
return city + "空气质量优";
}
}
}
3、定义代理类WeatherProxy
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ProxyPatternWeather
{
public class WeatherProxy:IWeather
{
Weather localweather;
public WeatherProxy()
{
//通过复杂的网络操作从远程得到相应数据
localweather = new Weather();
}
//在WeatherProxy代理类中也需要实现IWeather接口
public string GetTemperature(string city)
{
return localweather.GetTemperature(city);
}
public string GetWind(string city)
{
return localweather.GetWind(city);
}
public string GetAirQuality(string city)
{
return localweather.GetWind(city);
}
}
}
4、使用代理类获取相关信息
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ProxyPatternWeather
{
class Program
{
static void Main(string[] args)
{
WeatherProxy wp = new WeatherProxy();
string city = "BeiJing";
Console.WriteLine("通过WeatherProxy代理得到北京当天的天气情况:");
Console.WriteLine(wp.GetAirQuality(city));
Console.WriteLine( wp.GetTemperature(city));
Console.WriteLine(wp.GetWind(city));
Console.ReadLine();
}
}
}
总结:
1、代理的分类:按照使用目的来划
远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使(Ambassador)。
虚拟(Virtual)代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。
Copy-on-Write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。
保护(Protect or Access)代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。
Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
防火墙(Firewall)代理:保护目标,不让恶意用户接近。
同步化(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。
智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。
在所有种类的代理模式中,虚拟(Virtual)代理、远程(Remote)代理、智能引用代理(Smart Reference Proxy)和保护(Protect or Access)代理是最为常见的代理模式。
2、 一些可以使用代理模式(Proxy)的情况举例:
(1)、一个对象,比如一幅很大的图像,需要载入的时间很长。
(2)、一个需要很长时间才可以完成的计算结果,并且需要在它计算过程中显示中间结果
(3)、一个存在于远程计算机上的对象,需要通过网络载入这个远程对象则需要很长时间,特别是在网络传输高峰期。
(4)、一个对象只有有限的访问权限,代理模式(Proxy)可以验证用户的权限