在咱们的生活中,常常会遇到须要什么东西,可是本身又不是很方便或者对方不是很方便,则就须要中间的一个代理人去解决。例如代购。
在软件开发中,也会遇到这样的问题。有些对象有时候会因为网络或其余的障碍,以致于不可以或者不能直接访问到这些对象,若是直接访问对象给系统带来没必要要的复杂性,这时候能够在客户端和目标对象之间增长一层中间层,让代理对象代替目标对象,而后客户端只须要访问代理对象,由代理对象去帮咱们去请求目标对象并返回结果给客户端,这样的一个解决思路就是今天要介绍的代理模式。设计模式
代理是一种结构型设计模式, 让你能提供真实服务对象的替代品给客户端使用。 代理接收客户端的请求并进行一些处理 (访问控制和缓存等), 而后再将请求传递给服务对象。
代理对象拥有和服务对象相同的接口, 这使得当其被传递给客户端时可与真实对象互换。缓存
代理模式所涉及的角色有三个:安全
抽象主题角色(Person):声明了真实主题和代理主题的公共接口,这样一来在使用真实主题的任何地方均可以使用代理主题。服务器
代理主题角色(Friend):代理主题角色内部含有对真实主题的引用,从而能够操做真实主题对象;代理主题角色负责在须要的时候建立真实主题对象;代理角色一般在将客户端调用传递到真实主题以前或以后,都要执行一些其余的操做,而不是单纯地将调用传递给真实主题对象。例如这里的PreBuyProduct和PostBuyProduct方法就是代理主题角色所执行的其余操做。网络
真实主题角色(RealBuyPerson):定义了代理角色所表明的真是对象。工具
代理模式按照使用目的能够分为如下几种:性能
在上面全部种类的代理模式中,虚拟代理、远程代理、智能引用代理和保护代理较为常见的代理模式。测试
例如项目A的PM须要购买一个测试工具,可是测试工具的运营商在国外,本身过去不是很方便,因此须要找一个代理商帮助本身去购买。this
下面就实现此购买的例子:spa
using System; namespace Proxy { class Program { static void Main(string[] args) { ProgramManagement PM = new ProgramManagement(); PM.BuyToolName = "Bug管理工具"; PM.BuyTestTool(); ProxyBuyTestTool Tynam = new ProxyBuyTestTool(PM); Tynam.BuyTestTool(); Console.ReadKey(); } } public interface ITestTool { void BuyTestTool(); } public class ProgramManagement : ITestTool { public string BuyToolName; public void BuyTestTool() { Console.WriteLine($"项目A须要找一个代理商购买国外的一款{this.BuyToolName}的测试工具"); } } public class ProxyBuyTestTool : ITestTool { private ProgramManagement _pm; public ProxyBuyTestTool(ProgramManagement pm) { this._pm = pm; } public void BuyTestTool() { Console.WriteLine($"帮助项目A购买测试工具{this._pm.BuyToolName}成功"); } } }
运行后结果
项目A须要找一个代理商购买国外的一款Bug管理工具的测试工具
帮助项目A购买测试工具Bug管理工具成功
当没法或不想直接引用某个对象或访问某个对象存在困难时,能够经过代理对象来间接访问。使用代理模式主要有两个目的:一是保护目标对象,二是加强目标对象。
因为代理模式有许多分类,应用场景又适于多种状况: