好吧,这次的设计模式,我从最爱的足球谈起。
嗯,球员不是演员,想要行贿球员好比门将放球进去,这样演起来真的挺难,但作为裁判,对于一些争议性的问题,往往可以通过一些手段让他“看清”到底是哪方球员犯规在先,于是,球队老板们就决定跟裁判套套近乎了,可这必经是违法的事情,怎么办呢,一级官压死人,于是他们想到了足协,于是,球队老板-足协领导-裁判,就成了这proxy pattern的产业链,客户端-代理-服务端。
来看一下代码吧:
using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication1 { abstract class Intention { abstract public void ControlGame(); } class FTManager { public FTManager() { Console.WriteLine("shen yang hai shi lao ban:i can't ask the judge to do anything,so i turn to Football Association to get some help"); } public void BeginTheMatch() { FTAssociationProxy someBody = new FTAssociationProxy(); someBody.ControlGame(); } } class Judge:Intention { public override void ControlGame() { Console.WriteLine("huang jun jie:ok,let's begin,i can control this game 'fairly'"); } } class FTAssociationProxy { private Judge aJudge; public void ControlGame() { Console.WriteLine("nan yong:i'm the Football Association,i can order every judge"); if (aJudge == null) aJudge = new Judge(); aJudge.ControlGame(); } } class Program { static void Main(string[] args) { FTManager aManager = new FTManager(); aManager.BeginTheMatch(); } } }
作为代理,某些足协领导去寻求裁判帮助完成操纵比赛的任务要比球队老板直接联系裁判更方便,因为,领导和裁判,已经合作好久了。
好吧,来看一下这个入门理解很简单的proxy pattern:
定义
代理模式(Proxy)为另一个对象提供一个替身或占位符以控制对这个对象的访问,简而言之就是用一个对象来代表另一个对象。
代理模式非常常用,大致的思想就是通过为对象加一个代理来降低对象的使用复杂度、或是提升对象使用的友好度、或是提高对象使用的效率。
在我看来代理就好比是简单的封装,把一系列的问题通过统一的接口进行了规划,而我们通过这个代理,就可以有条理的实现一些复杂到我们不能实现的功能。
意图
提供其他对象一个代理或占位符,来控制该对象的访问权限。
缘由:
为什么我们要控制对象的访问权限呢?其中一个原因是通过控制来延迟对象的创建和实例化,直到真正需要使用该对象才进行创建和实例化。由于一些对象创建和实例化需要占用大量系统资源,但我们并不能确定用户一定会调用该对象,所以通过延迟对象实例化来减缓系统资源的消耗。例如文档编辑器如word,我们可以在里面插入链接、图片等,但是并不是我们每次打开word时都有创建和实例化这些对象,特别是实例化图片对象很消耗资源,而且我们有必要实例化所有图片吗?当我们在查看word时,只是看到其中的一部分,所以没有必要实例化所以资源,当我们看下一页时再实例化也不迟。例如webservice,当我们访问网络上一台计算机的资源时,我们正在跨越网络障碍,跨越网络障碍有时候是非常复杂,因为要确保数据安全可靠地传输。还好代理模式(Proxy)帮我们解决了其中的一些问题----WebService技术。通过对web的引用,我们可以实现对request和response的简单操作,这个代理把中间的过程都封装好了。
另外,在读取占用资源比较大的图片等内容的时候,我们可以先显示本地的备用图片,同时通过thread实现http的请求,请求结束后,让图片刷新显示,于是http作为我们的代理,实现了一些大图片的延迟显示。
代理种类:
1.远程(Remote)代理:
为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使(Ambassador)。
2.虚拟(Virtual)代理:
根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。
3.Copy-on-Write代理:
虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。
4.保护(Protect or Access)代理:
控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。
5.Cache代理:
为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
6.防火墙(Firewall)代理:
保护目标,不让恶意用户接近。
7.同步化(Synchronization)代理:
使几个用户能够同时使用一个对象而没有冲突。
8.智能引用(Smart Reference)代理:
当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。
何时采用
l代理模式应用非常广泛,如果你希望降低对象的使用复杂度、或是提升对象使用的友好度、或是提高对象使用的效率都可以考虑代理模式。
在现实生活中也有很多代理的角色,比如明星的经纪人,他就是一种代理,经纪人为明星处理很多对外的事情,目的是为了节省被代理对象也就是明星的时间。保险代理人帮助投保人办理保险,目的降低投保的复杂度。
在开发中代理模式也因为目的不同效果各不相同。比如,如果我们的网站程序是通过.NET Remoting来访问帐号服务的。在编写代码的时候可能希望直接引用帐号服务的DLL,直接实例化帐号服务的类型以方便调试。那么,我们可以引入Proxy模式,做一个帐号服务的代理,网站只需要直接调用代理即可。在代理内部实现正式和测试环境的切换,以及封装调用.NET Remoting的工作。
代理模式主要用与解决远程访问的传输问题,将复杂的网络传输封装到代理类里,这样让访问者能像使用本地方法一样使用代理方法,让网络对用户透明。但我认为代理模式远不止这些应用,只要是封装了复杂的变化,让用户使用方法进一步简化,都可以称之为代理。就像我可能根本不懂申请域名需要多少步骤,多说东西,但我知道有做域名代理的公司,直接找到那些公司一切都好说了,代理在我们的生活中是无处不在的。
实现要点
代理对象和被代理对象都遵循一致的接口。
在某些情况下,可以不必保持接口一致性,如果封装确实需要损失一些透明度,那么也可以认为是Proxy.
注意事项
Proxy、Facade以及Adapter可能都是对对象的一层封装,侧重点不同。Proxy基于一致的接口进行封装,Facade针对封装子系统,转化为高层接口,而Adapter的封装是处于适配接口的目的。
代理模式和装饰者:
意图:它们都提供间接访问对象层,都保存被调用对象的引用。
代理模式(Proxy):为另一个对象提供一个替身或占位符以控制对这个对象的访问,简而言之就是用一个对象来代表另一个对象。
装饰者(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,Decorator模式比生成子类更为灵活,它避免了类爆炸问题,像装饰者(Decorator),代理模式(Proxy)组成一个对象并提供相同的接口,但代理模式并不关心对象动态职能的增减。
在代理模式(Proxy)中Subject定义了主要的功能,而且Proxy根据Subject提供功能控制对象的访问权限。在装饰者(Decorator)中Component只是提供了其中的一些功能,需要通过装饰链动态给对象增加职能。
最后,还是像培训时候的PPT演讲一样,我一直都在谈论中国足球,当时教室外面总会有人路过的时候笑我一声,你看,这儿有谈中国足球的呢,其实,对于中超,足协变成这样那样,国足能力日趋下降,在我看来,不是球员问题,因为本质都在国家制度,国家对这个运动的普及程度,我们中国可选有很多,不像别的国家一样,比如韩国,昨晚韩国的男人,生下来不踢足球就不叫男人,比如英国,德国,他们几乎每个人都有自己信仰的一支足球队,比如非洲国家,再穷,也会有一个足球伴着孩子们的成长,但在我们中国不是,我们中国不算穷,不算富,我们走的是平庸化,我们一直都在学习,我们可选的目标有很多,可走的运动有很多,而对于足球,从我们的信仰里,好像早已经被剔除出去了,再谈国足或者中超战绩的时候,请国民,请那些自称为球迷的人,认识到你自己的信仰,你是想在欧洲杯时候跟自己国家的球迷对骂来支持那欧洲的球队,还是做一个真正的球迷找到自己钟爱的自己的球队,找到自己对于国家对于自己国家这项赛事的信仰。
如果你说你是一个真球迷,那么,请信仰。
(初涉设计模式,希望大家看到不足和缺陷能随时指出,一起学习一下。。。)
转载请注明出处:Edward_jie,http://www.cnblogs.com/promise-7/archive/2012/05/25/2518344.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述